簡體   English   中英

停止重新渲染父組件。 僅重新渲染子組件

[英]Stop Re-Rendering of Parent Components. Only Re-Render Child Component

我在 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--問題:使組件僅保留其自身的渲染。 其中使用的外部組件FormikReact-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 prop 是使樹上的旅程,到主窗體 Props,並重新渲染整個組件樹的原因。 這也與我昨天遇到的另一個問題有關,關於 react-select 的closeMenuOnSelect={false}無法正常工作。

^這就是發生這種情況的原因。 謝謝..

我不知道您如何使用您正在使用的庫來做到這一點。 但是當我不希望我的組件不必要地渲染時,我使用React.memo它會淺比較props對象並決定是否需要更新。

來自 React DOCS

無反應備忘錄

 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"/>

帶有反應備忘錄

 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"/>

我會檢查 Formik 的 onSubmit 是否被調用,以及是否觸發了樹重新渲染。 如果您有一個type=button可能會觸發表單提交。

在 v2 之前的 Formik 也有一個錯誤,如果通過rendercomponent道具給定渲染功能,則 Field 將在每次更新時掛載和卸載它的所有子項。 而是將渲染函數作為 Fields 子項傳遞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM