有条件地重新呈现React组件

时间:2019-03-26 10:56:30

标签: javascript reactjs redux

让我们看看我们有一个Form组件:

//...
const formsReducer = (forms = {}, action) => {
  switch (action.type) {
    case "CREATE_FORM" : {
      const { id, inputIds } = action;

      return {
        ...forms,
        [id]: inputIds.reduce((inputs, inputId) => {

          inputs[inputId] = "";

          return inputs;
        }, {})
      };
    };
    default : return forms
  };
};
//...
import React, { useEffect } from "react";
import { connect } from "react-redux";

const createForm = (id, inputIds) => ({
  type: "CREATE_FORM",
  id,
  inputIds
})

const Form = ({
    id,
    inputs,
    onSubmit,

    createForm,

    getState //!!
}) => {

  useEffect(() => {
      createForm(id, inputs.map(({ inputId }) => inputId))
  }, []);

  submit = () => {
    const inputValues = getState().forms[id];

    onSubmit(inputValues);
  };

  return (
    <div className="form">
      {inputs.map(props => <Input {...props} />)
      <button onClick={submit}>Submit</button>
    </div>
  )

};

const mapDispatchToProps = { createForm };

export default connect(null, mapDispatchToProps)(Form);

其中输入将其值分配到redux存储中。我想要获得的并不是不必要地重新渲染Form组件,但是它应该知道提交时的输入值。上面带有getState的示例可能是一个很好的解决方案,但首先,我不知道实现该解决方案的任何可能的解决方案。

其次,它将获得整个redux状态(这对性能不利)。我想到的是使用“提交”按钮调度事件(例如,它设置state.forms[formId].submit = true,并监听它,并使用FormmapStateToProps输入值,但是在上面设置一个React.memo,然后将shouldComponentUpdate = (prev, next) => prev.submit !== next.submit作为第二个参数传递。

这样,Form会更新,如果它获得“绿灯”,并且如果submit为真,它将使用来自{{1}的输入值调用onSubmit }。我想到的第三个解决方案是将按钮作为组件,并听取表单中的所有更改。重新渲染按钮并不像每次重新渲染整个表单那样昂贵。对于这种情况,最有效的解决方案是什么?

1 个答案:

答案 0 :(得分:0)

除非您正在使用Redux表单或需要在应用程序的其他位置访问该数据,否则您不应在Redux中存储表单状态。组件状态是诸如表单状态之类的更好的解决方案。如果您希望对字段的更新显示在屏幕上,则必须重新呈现表单的某些部分。使用组件状态意味着您仅重新呈现表单,而不是整个应用程序。这应该是性能上的明智选择。设置好表单数据并进行验证后,然后在提交时触发调度功能,并将所有内容重新绑定到redux。