为什么我的嵌套组件会自行重建?

时间:2019-05-05 13:48:46

标签: javascript reactjs nested custom-component rerender

我正在尝试基于本机输入/范围元素构建自定义滑块。汇总的代码如下所示:

const Slider = ({ className, backgroundColor, ...inputAttributes }) => {
  const [value, setValue] = useState(5);

  const handleSliderChange = event => {
    setValue(event.currentTarget.value);
  };

  const SliderElement = () => (
    <input value={value} onChange={handleSliderChange} {...inputAttributes} />
  );

  // ...

  return (
    <>
      <SliderElement />
      <p>
        <Display>{value}</Display>
      </p>
    </>
  );
};

这样称呼:

<Slider type="range" min={1} max={10} step={1} />
  

此处的完整运行代码:https://codesandbox.io/s/000qm47pjw

     

带有嵌套的SliderElement组件

使用上面的代码,我一次只能将滑块移动一个步骤(我必须“取消单击”滑块,然后再次单击它以进行下一步)。我怀疑是因为SliderElement每次我移动滑块时都会被重新渲染。

但是...

如果我完全跳过SliderElement并将<input...直接放到返回的JSX中,它将完美地工作。

  

此处的完整运行代码:https://codesandbox.io/s/5469y582yn

     

不包含嵌套的SliderElement组件


为什么每次使用SliderElement时都会重新呈现(假设是这种情况)?

如何将<input...包裹在嵌套的组件中,并且仍然能够提供黄油般的流畅体验?

1 个答案:

答案 0 :(得分:2)

区分这两个:

var aReactElement = <input />
var aReactComponent = () => <input />

React组件负责决定是否应重新呈现其管理的React元素。它在一个前提下工作,组件对象 instance 应该保持不变,以便用作某个持久状态的引用键。

在您的示例中,SliderElement实例在Slider的每次重新渲染中都在不断变化,它每次都是新功能。因此,您的DOM树会不断卸载,然后再安装<input />元素。

您可以使它成为元素,而不是使SliderElement成为组件。

const SliderElement = (
    <input value={value} onChange={handleSliderChange} {...inputAttributes} />
  );

  // ...

  return (
    <>
      {SliderElement}
      <p>
        <Display>{value}</Display>
      </p>
    </>
  );