我正在尝试基于本机输入/范围元素构建自定义滑块。汇总的代码如下所示:
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...
包裹在嵌套的组件中,并且仍然能够提供黄油般的流畅体验?
答案 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>
</>
);