为什么我的嵌套组件会自行重建?
Why is my nested component rebuilding itself?
我正在尝试基于原生 input/range 元素构建自定义滑块。汇总代码如下所示:
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} />
Full running code here: https://codesandbox.io/s/000qm47pjw
w/ nested SliderElement component
使用上面的代码,我一次只能移动滑块一步(我必须 "unclick" 滑块并再次单击它才能进行下一步)。我怀疑这是因为每次移动滑块时 SliderElement
都会重新渲染。
然而...
如果我完全跳过 SliderElement
并将 <input...
直接放入返回的 JSX 中,它会完美运行。
Full running code here: https://codesandbox.io/s/5469y582yn
w/o nested SliderElement component
为什么 SliderElement
每次使用它时都会重新渲染(假设是这种情况)?
如何让 <input...
包裹在嵌套组件中,并且仍然能够提供黄油般流畅的体验?
区分这两个:
var aReactElement = <input />
var aReactComponent = () => <input />
一个反应组件负责决定是否应该重新渲染它管理的反应元素。它在一个前提下工作,组件对象 instance 应该保持不变,以便作为一个持久状态的引用键。
在您的示例中,SliderElement
实例在 Slider
的每次重新渲染中不断变化,每次都是一个新函数。因此,您的 DOM 树不断卸载然后安装 <input />
元素。
您可以将其设为元素,而不是将 SliderElement
设为组件。
const SliderElement = (
<input value={value} onChange={handleSliderChange} {...inputAttributes} />
);
// ...
return (
<>
{SliderElement}
<p>
<Display>{value}</Display>
</p>
</>
);
我正在尝试基于原生 input/range 元素构建自定义滑块。汇总代码如下所示:
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} />
Full running code here: https://codesandbox.io/s/000qm47pjw
w/ nested SliderElement component
使用上面的代码,我一次只能移动滑块一步(我必须 "unclick" 滑块并再次单击它才能进行下一步)。我怀疑这是因为每次移动滑块时 SliderElement
都会重新渲染。
然而...
如果我完全跳过 SliderElement
并将 <input...
直接放入返回的 JSX 中,它会完美运行。
Full running code here: https://codesandbox.io/s/5469y582yn
w/o nested SliderElement component
为什么 SliderElement
每次使用它时都会重新渲染(假设是这种情况)?
如何让 <input...
包裹在嵌套组件中,并且仍然能够提供黄油般流畅的体验?
区分这两个:
var aReactElement = <input />
var aReactComponent = () => <input />
一个反应组件负责决定是否应该重新渲染它管理的反应元素。它在一个前提下工作,组件对象 instance 应该保持不变,以便作为一个持久状态的引用键。
在您的示例中,SliderElement
实例在 Slider
的每次重新渲染中不断变化,每次都是一个新函数。因此,您的 DOM 树不断卸载然后安装 <input />
元素。
您可以将其设为元素,而不是将 SliderElement
设为组件。
const SliderElement = (
<input value={value} onChange={handleSliderChange} {...inputAttributes} />
);
// ...
return (
<>
{SliderElement}
<p>
<Display>{value}</Display>
</p>
</>
);