简体   繁体   English

从表单反应更新 state

[英]React update state from a form

I am trying to get values from a form and store it in state.我正在尝试从表单中获取值并将其存储在 state 中。 Every time I follow a guide I get the following error (not to mention the guides are all in the class style react):每次我遵循指南时,都会收到以下错误(更不用说指南都是 class 风格的反应):

"Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." “渲染没有返回任何内容。这通常意味着缺少返回语句。或者,不渲染任何内容,返回 null。”

The component renders and I can even pass in a dummy value to the step.generalInfo.name and it shows up on the component.组件呈现,我什至可以将一个虚拟值传递给 step.generalInfo.name,它会显示在组件上。 However, as soon as I press a key into the input, boom error.但是,只要我按一个键进入输入,繁荣错误。 I think the error is in one of two places - either my handleChange() or the way I am trying to update the state as I am trying to get a value in an object inside another object.我认为错误出现在两个地方之一 - 我的 handleChange() 或我尝试更新 state 的方式,因为我试图在另一个 object 中获取一个值。 I am probably not destructuring or prop drilling correctly.我可能没有正确解构或支撑钻孔。 Please help!请帮忙! Thanks!谢谢!

App() renders the form below: App() 呈现如下形式:

function Form() {
  const [step, setStep] = useState({
    stage: 1,
    generalInfo: {
      name: "",
      batchSize: "",
      batchType: "",
      batchNumber: "",
      ibu: "",
      srm: "",
      abv: "",
      origionalGravity: "",
      finalGravity: "",
      brewingDate: "",
      dateSecondary: "",
      dateBottling: "",
    },
    ingredients: ["", "", ""],
    brewingNotes: "",
    hopsNotes: "",
    yeastNotes: "",
    fermentationNotes: "",

...More state and next/prev page functions... ...更多 state 和下一页/上一页功能...

  const handleChange = (e) => {
    console.log(e);
    console.log(e.target.name);
    console.log(e.target.value);
    setStep({ [e.target.name]: e.target.value });
    console.log(step);
  };
  const handleSubmit = (e) => {
    e.preventDefault();
  };
  switch (step.stage) {
    case 1:
      return (
        <StepOne
          step={step}
          next={next}
          prev={prev}
          handleChange={handleChange}
          setStep={setStep}
        />
      );
  }
}

export default Form;

StepOne Component is below: StepOne 组件如下:

function StepOne({ step, next, prev, handleChange, setStep }) {
  const {
    name,
    batchSize,
    batchType,
    batchNumber,
    ibu,
    srm,
    abv,
    origionalGravity,
    finalGravity,
    brewingDate,
    dateSecondary,
    dateBottling,
  } = step.generalInfo;

  return (
    <div className="form-container">
      <h1>General Info</h1>
      <form>
        <div className="label-group">
          <label>Name:</label>
          <input type="text" name="name" onChange={handleChange} />
        </div>
        <button onClick={next}>Next</button>
      </form>
    </div>
  );
}

export default StepOne;

I believe its setStep within your handleChange method我相信它在您的 handleChange 方法中的 setStep

setStep({ [e.target.name]: e.target.value });

useState doesn't merge in the same way this.setState does, therefor stage is getting overwritten and your switch statement doesn't return a render. useState 不会以与 this.setState 相同的方式合并,因此阶段被覆盖并且您的 switch 语句不会返回渲染。

You instead need to pass a function to iterate state相反,您需要传递 function 来迭代 state

setStep((state) => ({...state, generalInfo: {...state.generalInfo, [e.target.name]: e.target.value}}))

But given the amount of nesting, the location of e.target.name would be verbose to find;但是考虑到嵌套的数量,e.target.name 的位置很难找到; you would benefit a lot from using useReducer instead of useState.你会从使用 useReducer 而不是 useState 中受益匪浅。

Your function handleChange is incorrect, it remove all the field in state step except the current changed field.您的 function handleChange不正确,它删除了 state step中的所有字段,但当前更改的字段除外。 That could lead to another component will crash if it is using data from state step如果使用 state step中的数据,这可能会导致另一个组件崩溃

It should be它应该是

const handleChange = (e) => {
    console.log(e);
    console.log(e.target.name);
    console.log(e.target.value);
    setStep({ ...step, [e.target.name]: e.target.value }); <= HERE
    console.log(step);
};

Fixing handleChange was the key!修复 handleChange 是关键!

  const handleChange = (e) => {
    e.persist();
    console.log(e);
    console.log(e.target.name);
    console.log(e.target.value);
    setStep((state) => ({
      ...state,
      generalInfo: { ...state.generalInfo, [e.target.name]: e.target.value },
    }));
    console.log(step);
  };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM