javascript - 停止父组件的重新渲染。仅重新渲染子组件

标签 javascript reactjs render react-select formik

我在 Formik 字段内有一个 React-Select 字段,当您从下拉选项中选择一个项目时,所有父组件都会重新渲染。这是容器中可用的最深的子组件。

它重新渲染了 4 个 parent 。这是有问题的。我想将组件的重新渲染限制为仅其自身。

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 属性负责沿着树向上到达主表单 Props,并重新渲染整个组件树。这也与我昨天遇到的另一个问题有关,即react-select的 closeMenuOnSelect={false} 无法正常工作。

^这就是发生这种情况的原因。谢谢..

最佳答案

我不知道您如何使用您正在使用的库来做到这一点。但是,当我不想让我的组件不必要地渲染时,我使用React.memo,它会浅比较props对象并决定是否需要更新。

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

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

关于javascript - 停止父组件的重新渲染。仅重新渲染子组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56665605/

相关文章:

Javascript 在将 'px' 分配给变量时删除位置值

javascript - React createElement 子级语法

javascript - super react ,无法读取未定义的属性 'call'

javascript - 如何使用 JavaScript 将文件读取到 WebAssembly?

javascript - Disqus 的 iframe 如何根据其中的内容自行调整大小?

javascript - 禁用选定行的 href 链接

reactjs - VSCode 不会在 typescript 中导入 <Text> 组件

ruby-on-rails - ul li 中的 Rails 渲染集合

html - PDF 不呈现 Html Css ASP.NET

Java 渲染仅相交?