从表单反应更新状态

时间:2020-07-11 02:08:24

标签: javascript reactjs jsx

我正在尝试从表单获取值并将其存储在状态中。每次我遵循指南时,都会遇到以下错误(更不用说指南都是以类样式进行响应的):

“渲染未返回任何内容。这通常意味着返回 声明丢失。或者,要不显示任何内容,请返回null。”

该组件将呈现,我甚至可以将虚拟值传递给step.generalInfo.name,它会显示在该组件上。但是,一旦我在输入中按下一个键,便会发出动臂错误。我认为错误是在两个位置之一发生的-我的handleChange()或试图在另一个对象内部的对象中获取值时尝试更新状态的方式。我可能没有正确进行销毁或支撑钻探。请帮忙!谢谢!

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: "",

...更多状态和下一页/上一页功能...

  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组件如下:

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;

3 个答案:

答案 0 :(得分:0)

我相信它在您的handleChange方法中的setStep

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

useState不会像this.setState那样合并,因此舞台将被覆盖,并且您的switch语句不会返回渲染。

您需要传递一个函数来迭代状态

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

但是考虑到嵌套的数量,找到e.target.name的位置会很麻烦;使用useReducer而不是useState将会使您受益匪浅。

答案 1 :(得分:0)

您的函数handleChange不正确,它删除了状态step中除当前更改的字段以外的所有字段。 如果它正在使用状态step

中的数据,则可能导致另一个组件崩溃

应该是

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);
};

答案 2 :(得分:0)

修复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);
  };