我在Formik字段中有一个React-Select字段,当您从下拉选项中选择一个项目时,所有父组件都将重新呈现。这是容器中可用的最深的子组件。
它重新渲染了4个父母。这有点问题。我想将组件的重新呈现限制为仅自身。
The above happens because each Child Process passes
props to the Container, which is the master form.
And onSubmit it takes all the info(props) and makes the API Call.
我尝试用shouldComponentUpdate
来做到这一点,但是没有运气。我试图用SetState
来做到这一点,但这虽然掉进了水里,但我却无法正常工作(出现了很多错误)。
-TLDR-
问题:
使组件仅将渲染保留到其自身。 Formik
和React-Select
中使用的外部组件。
这是代码:
<div className="w-50">
<Field
name={`${keyField}.${index}.permissions`}
render={({ field: { value, name }, form: { setFieldValue, setFieldTouched } }) => (
<div>
<label htmlFor="namespace-permissions" className="font-weight-medium">
Permissions in Namespace <Asterisk />
</label>
<Select
isMulti
closeMenuOnSelect={false}
id="namespace-permissions"
defaultValue={convertNamespaceToDefaultValue(
dependencies.namespacePermissions,
value
)}
options={convertNamespaceToSelect(dependencies.namespacePermissions)}
onChangeCallback={values => {
setFieldValue(name, convertSelectToNamespacesData(values));
setFieldTouched(name, true);
}}
/>
<ErrorMessage name={name} component={FormErrorMessage} />
</div>
)}
/>
</div>
dependacies
道具可以使这棵树跳到主表单Props,并重新渲染整个组件树。这也与我昨天遇到的另一个问题有关,即react-select的closeMenuOnSelect={false}
无法正常工作。
^这是发生这种情况的原因。谢谢你。
答案 0 :(得分:1)
我不知道您将如何使用正在使用的库来执行此操作。但是,当我不想让我的组件不必要地渲染时,我会使用React.memo
来比较props
对象,并确定是否需要更新。
没有反应备忘录
function App() {
return(
<Parent1/>
);
}
function Parent1(props) {
console.log('Rendering Parent1...');
const [parentState,setParentState] = React.useState(true);
return(
<Parent2
setParentState={setParentState}
/>
);
}
function Parent2(props) {
console.log('Rendering Parent2...');
return(
<Child
setParentState={props.setParentState}
/>
);
}
function Child(props) {
console.log('Rendering Child...');
return(
<button onClick={()=>props.setParentState((prevState)=>!prevState)}>Update ParentState</button>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
具有REACT.MEMO
function App() {
return(
<Parent1/>
);
}
function Parent1(props) {
console.log('Rendering Parent1...');
const [parentState,setParentState] = React.useState(true);
return(
<Parent2
setParentState={setParentState}
/>
);
}
const Parent2 = React.memo(function Parent2(props) {
console.log('Rendering Parent2...');
return(
<Child
setParentState={props.setParentState}
/>
);
}
);
const Child = React.memo(function Child(props) {
console.log('Rendering Child...');
return(
<button onClick={()=>props.setParentState((prevState)=>!prevState)}>Update ParentState</button>
);
}
);
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
答案 1 :(得分:0)
我将检查是否调用了Formik的onSubmit,并且是否正在触发树的重新渲染。如果您有一个带有type=button
的按钮,可能会触发表单提交。
v2之前的Formik也存在一个错误,即如果通过render
或component
属性提供了render函数,则每次更新时Field都会安装和卸载所有子级。相反,只需将render函数作为Fields子级传递。