防止在功能道具更新时重新呈现

我有一个包含几层子组件的表单。表单的状态保持在最高级别,而我向下传递了作为更新最高级别的道具的函数。唯一的问题是,当表单变得很大(您可以动态添加问题)时,每个单个组件都会在其中一个更新时重新加载。这是我的代码的简化版本(或codesandbox:https : //codesandbox.io/s/636xwz3rr ):


const App = () => {

  return <Form />;

}


const initialForm = {

  id: 1,

  sections: [

    {

      ordinal: 1,

      name: "Section Number One",

      questions: [

        { ordinal: 1, text: "Who?", response: "" },

        { ordinal: 2, text: "What?", response: "" },

        { ordinal: 3, text: "Where?", response: "" }

      ]

    },

    {

      ordinal: 2,

      name: "Numero dos",

      questions: [

        { ordinal: 1, text: "Who?", response: "" },

        { ordinal: 2, text: "What?", response: "" },

        { ordinal: 3, text: "Where?", response: "" }

      ]

    }

  ]

};


const Form = () => {

  const [form, setForm] = useState(initialForm);


  const updateSection = (idx, value) => {

    const { sections } = form;

    sections[idx] = value;

    setForm({ ...form, sections });

  };


  return (

    <>

      {form.sections.map((section, idx) => (

        <Section

          key={section.ordinal}

          section={section}

          updateSection={value => updateSection(idx, value)}

        />

      ))}

    </>

  );

};


const Section = props => {

  const { section, updateSection } = props;


  const updateQuestion = (idx, value) => {

    const { questions } = section;

    questions[idx] = value;

    updateSection({ ...section, questions });

  };


  console.log(`Rendered section "${section.name}"`);


  return (

    <>

      <div style={{ fontSize: 18, fontWeight: "bold", margin: "24px 0" }}>

        Section name:

        <input

          type="text"

          value={section.name}

          onChange={e => updateSection({ ...section, name: e.target.value })}

        />

          />

        ))}

      </div>

    </>

  );

};

我已经尝试过使用useMemo和useCallback,但是我不知道如何使它工作。问题是传递函数以更新其父级。我无法弄清楚如何在每次表单更新时不对其进行更新。


我无法在任何地方在线找到解决方案。也许我在寻找错误的东西。感谢您提供的任何帮助!


慕田峪7331174
浏览 129回答 3
3回答

慕桂英4014372

通过使用复杂的表单解决此问题,我实现的技巧是onBlur={updateFormState}通过组件的prop传递给组件的输入元素上触发将表单数据从组件提升到父表单。为了更新组件的输入要素,我onChange={handleInput}使用了组件内部的状态,然后当输入(或组件作为一个整体,如果组件中有多个输入字段)失去焦点时,通过提升功能将组件状态传递给组件。这有点hacky,并且由于某种原因可能是错误的,但是它在我的机器上可以工作。;-)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript