React Native 在父零部件中包含零部件的效果

vcudknz3  于 2023-05-07  发布在  React
关注(0)|答案(3)|浏览(109)

关于react rerendering和mount/unmount我有这个问题。如果我们在另一个父功能组件中定义了一个组件,并且父组件的状态发生了变化,很明显父组件将重新呈现。

问题:但是,在它内部定义的子功能组件是否也会重新渲染,或者它会卸载然后再次挂载?

我使用下面的代码作为这个问题的参考。下面代码的问题是,当用户输入时,每次击键后焦点都会丢失(或者在react-native的情况下键盘会消失),作者给出的原因是当Form函数重新呈现时,子函数会重新声明。但我不确定它的意思是重新声明,这意味着它得到重新渲染或得到卸载,并得到再次挂载?根据作者的说法,解决这个问题的方法是传递{Input()}或在父窗体组件之外定义子组件。这是原始文章https://levelup.gitconnected.com/code-review-avoid-declaring-react-component-inside-parent-component-1768a645f523的链接

import { useState } from 'react';

const Form = () => {
  const [values, setValues] = useState(['', '']);

  const onChange = (value, index) => {
    const newValues = [...values];
    newValues[index] = value;
    setValues(newValues);
  };

  const Input = (props) => {
    return <input type='text' {...props} />;
  };

  return (
    <>
      {values.map((value, index) => (
        <Input
          key={index}
          value={value}
          onChange={(e) => onChange(e.target.value, index)}
        />
      ))}
      <button onClick={() => setValues([...values, ''])}>Add</button>
    </>
  );
};
gxwragnw

gxwragnw1#

在React中,当父组件经历重新渲染时,其子组件也会自动重新渲染。在所提供的代码示例中,子组件“Input”在父组件“Form”内定义。因此,每当“Form”被重新渲染时,“Input”的新示例被创建。
这意味着当状态改变触发“表单”组件的重新渲染时,“输入”组件也经历重新渲染。但是,由于每次重新呈现“Form”时都会生成“Input”的新示例,因此将卸载“Input”的先前示例,并安装新示例以替换它。
这可能会导致一些问题,比如每次击键时键盘都会消失,因为新安装的“Input”示例不会保持与前一个示例相同的焦点状态。为了避免这样的问题,可以在“Form”组件之外定义“Input”组件,这允许在“Form”的每次重新渲染上重用“Input”的相同示例。
总结一下,默认情况下,当父组件在React中重新渲染时,其子组件也会重新渲染。但是,如果在父组件内部定义了子组件,则在每次重新呈现父组件时都会重新声明它,这会导致旧示例被卸载,新示例被挂载到它的位置

bq3bfh9z

bq3bfh9z2#

要理解这一点,您必须了解reconciliation算法。
当在一个render react中看到树层次结构中的某个组件时,说:

...
<ComponentA/>
 ...

然后在下一个渲染中,它会看到一个不同的组件

...
<ComponentB/>
 ...

在树层次结构中的相同位置,卸载ComponentA,并挂载ComponentB

现在,当你在另一个组件内部定义一个组件时,当外部组件重新渲染时,内部组件函数(用于创建组件的函数)重新创建,react会认为它是不同的组件类型(因为函数引用现在不同了)。因此,我们得到与ComponentAComponentB类似的情况。
这就是为什么组件必须在外部定义的原因。当它在外部定义时,用于创建组件的函数在重新渲染之间保持不变(引用也不会改变)。在这种情况下,重新渲染父对象将简单地导致子对象重新渲染,而无需卸载。

js81xvg6

js81xvg63#

子组件(Input)在父组件(Form)内部定义。每次父组件重新呈现时,子组件(Input)的函数都将重新声明。这意味着子组件将被重新安装,这意味着在父组件的每次重新渲染中,子组件都是一个新功能。这就是为什么每次按下键时焦点都会丢失。

相关问题