让我们看看我们有一个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
,并监听它,并使用Form
至mapStateToProps
输入值,但是在上面设置一个React.memo
,然后将shouldComponentUpdate = (prev, next) => prev.submit !== next.submit
作为第二个参数传递。
这样,Form
会更新,如果它获得“绿灯”,并且如果submit
为真,它将使用来自{{1}的输入值调用onSubmit
}。我想到的第三个解决方案是将按钮作为组件,并听取表单中的所有更改。重新渲染按钮并不像每次重新渲染整个表单那样昂贵。对于这种情况,最有效的解决方案是什么?
答案 0 :(得分:0)
除非您正在使用Redux表单或需要在应用程序的其他位置访问该数据,否则您不应在Redux中存储表单状态。组件状态是诸如表单状态之类的更好的解决方案。如果您希望对字段的更新显示在屏幕上,则必须重新呈现表单的某些部分。使用组件状态意味着您仅重新呈现表单,而不是整个应用程序。这应该是性能上的明智选择。设置好表单数据并进行验证后,然后在提交时触发调度功能,并将所有内容重新绑定到redux。