Joh*_*uel 6 javascript reactjs react-hooks
需要建议在反应的功能组件中发挥作用Hooks。
据我研究,很多人都说这是不好的做法,因为每次我们称为重新渲染时,它都会创建嵌套/内部函数。经过分析,
我发现我们可以onClick={handleClick.bind(null, props)}在元素上使用并将功能放置在功能组件之外。
例:
const HelloWorld = () => {
function handleClick = (event) => {
console.log(event.target.value);
}
return() {
<>
<input type="text" onChange={handleClick}/>
</>
}
}
Run Code Online (Sandbox Code Playgroud)
请告知是否还有其他方法。
提前致谢。
Arn*_*ugo 26
不要担心在每个渲染上创建新函数。只有在边缘情况下才会妨碍您的表现。设置onClick处理程序不是其中之一,因此只需在每个渲染上创建一个新函数。
但是,当您需要确保每次都使用相同的函数时,可以使用useCallback
useCallback用于onClick这是您不应该useCallback为onClick处理程序(和大多数其他事件处理程序)烦恼的原因。
考虑以下代码片段,其中一个没有 useCallback:
function Comp(props) {
return <button onClick={() => console.log("clicked", props.foo)}>Text</Button>
}
Run Code Online (Sandbox Code Playgroud)
和 useCallback 之一:
function Comp(props) {
const onClick = useCallback(() => {
console.log("clicked", props.foo)
}, [props.foo])
return <button onClick={onClick}>Text</Button>
}
Run Code Online (Sandbox Code Playgroud)
后者的唯一区别是 React 必须更改onClick按钮上的props.foo保持不变。
更改回调是一个非常便宜的操作,为了理论上的性能改进,它根本不值得让您的代码复杂化。
此外,值得注意的是,
即使您使用,每次渲染时仍会创建一个新函数useCallback,但useCallback只要作为第二个参数传递的依赖项未更改,就会返回旧函数。
useCallback使用的要点useCallback是,如果将两个函数与引用相等进行比较,fn === fn2则仅当fn和fn2指向内存中的同一函数时才为真。功能是否相同并不重要。
因此,如果您有记忆或仅在函数更改时运行代码,useCallback再次使用相同的函数会很有用。
例如,React 钩子比较旧的和新的依赖项,可能使用Object.is。
另一个例子是React.PureComponent,它只会在 props 或 state 改变时重新渲染。这对于使用大量资源进行渲染的组件很有用。例如onClick,在每次渲染时将new 传递给 PureComponent 将导致它每次重新渲染。
Jon*_*lms 11
许多人说这是不好的做法,因为每次我们调用重新渲染时它都会创建嵌套/内部函数
不,内部函数/闭包是如此常见,它们没有问题。引擎可以对这些进行大量优化。
这里的重点是您将函数作为道具传递给子组件。并且由于函数是“重新创建”的,它不等于先前传递的函数,因此子函数会重新渲染(这对性能不利)。
您可以使用 来解决该问题useCallback,它会记住函数引用。
useCallback您可以使用useCallback功能:
const HelloWorld = ({ dispatch }) => {
const handleClick = useCallback((event) => {
dispatch(() => {console.log(event.target.value)});
})
return() {
<>
<input type="name" onChange={handleClick}/>
</>
}
}
Run Code Online (Sandbox Code Playgroud)
useCallback将返回回调的记忆版本,该版本仅在依赖项之一发生更改时才会更改。这在将回调传递给依赖引用相等的优化子组件时很有用,以防止不必要的渲染(例如 shouldComponentUpdate)。
有关更多详细信息,请访问 react 文档参考:React useCallback
第一个解决方案:将您的handleClick功能传递给您的功能组件。
const HelloWorld = (props) => {
return() {
<>
<input type="name" onChange={props.handleClick}/>
</>
}
}
Run Code Online (Sandbox Code Playgroud)
第二种解决方案:在功能组件之外定义您的功能。
有趣的问题,我和我的同事对此有些担心,所以我做了一个测试。
我创建了 1 个带钩子的组件和 1 个带类的组件,在那里放置了一些函数,然后将其渲染 1000 倍。
带有类的组件如下所示:
export class ComponentClass extends React.PureComponent {
click1 = () => {
return console.log("just a log");
};
render() {
return (
<>
<span onClick={this.click1}>1</span>
</>
);
}
}
Run Code Online (Sandbox Code Playgroud)
带钩子的组件如下所示:
export const ComponentHook = React.memo((props) => {
const click1 = () => {
return console.log("just a log");
};
return (
<>
<span onClick={click1}>1</span>
</>
);
});
Run Code Online (Sandbox Code Playgroud)
我在组件中添加了更多的点击处理程序,然后渲染它们大约 1000 次,类更快,因为它没有定义每次渲染的函数,如果增加定义的函数数量,那么差异会更大:
这是一个代码沙箱,因此您可以测试性能 Class vs Hooks:https ://codesandbox.io/s/hooks-vs-class-forked-erdpb