Cas*_*raH 2 reactjs react-dom react-hooks usecallback
请跟随我的代码段下面,当我点击任何按钮(添加,编辑,删除)我所有的部件得到重新渲染,包括Title它没有成分props或stats。如果我有几个组件可能没问题,但假设我有超过15 个或更多的组件来获取/保存数据,这是可以的还是应该避免?
我尝试使用useCallback钩子(使用handleRemove),但显然这不能按预期工作。
const Button = ({ title, count, onClick }) => {
console.log(`Rendering ${title}`)
return (
<button onClick={onClick}>
{title} ({count})
</button>
)
}
const Header = () => {
console.log("Rendering Title")
return <h1>App Title</h1>
}
const Parent = () => {
const [add, setAdd] = React.useState(0)
const [edit, setEdit] = React.useState(0)
const [remove, setRemove] = React.useState(0)
const handleAdd = () => setAdd(add + 1)
const handleEdit = () => setEdit(edit + 1)
const handleRemove = React.useCallback(() => {
setRemove(remove + 1)
}, [remove])
return (
<React.Fragment>
<Header />
<Button title="Add" onClick={handleAdd} count={add} />
<Button title="Edit" onClick={handleEdit} count={edit} />
<Button title="Remove" onClick={handleRemove} count={remove} />
</React.Fragment>
)
}
function App() {
return (
<div className="App">
<Parent />
<button onClick={console.clear}>Clear log</button>
</div>
)
}
ReactDOM.render( <App /> , document.getElementById('root'))Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>Run Code Online (Sandbox Code Playgroud)
评论和另一个答案中有一些更高级的信息,但我想解决一些关于 React 工作原理的更基本的问题,以及:
如果我有几个组件可能没问题,但假设我有超过 15 个或更多的组件来获取/保存数据,这是可以的还是应该避免?
在 React 中,即使一个组件被“重新渲染”......在它的函数被重复调用的意义上......它不会在最重要(即昂贵)的地方“重新渲染”:在实际DOM。或者更确切地说,除非函数返回不同的东西,否则它不会。
因此,每次您console.log在 React 组件中看到 a时,都只意味着涉及到虚拟DOM,因此这种更改的成本要低得多(同样,假设您的组件不断返回相同的 JSX)。
现在当然任何函数调用仍然有成本,并且您希望最终最大限度地减少组件渲染的次数,但同时重要的是要记住著名程序员 Donald Knuth 的话:
过早优化是万恶之源
如果您甚至连最轻微的性能问题都没有看到,那么担心组件在虚拟 DOM 中渲染的确切次数会让您错过 React 的一些天才:您交易了大量的人类甚至无法观察到的用于“性能优化”的昂贵资源(您的想法)。
相反,您绝对想阅读有关该库的更多信息,了解是什么触发了渲染调用(本质上是 props/state/context 更改,但有重要的细节),并尝试以这种方式理解和提高性能。学习 React 中“升级”的所有内容。
但是,特别是如果你只是在学习这个库,你真的不需要担心重新渲染任何特定的组件几次,因为 React 的设计非常巧妙,让我们专注于我们的组件做什么,而不是确切地说它是如何完成的......或者至少大部分时间(我当然不想让它听起来像 React 是一个“神奇的性能子弹”)。