我正在用React Hooks编写我的产品,是的,我是新手。
今天我有关于useCallback的数学,performance.This让我考虑了很多关于使用或不使用useCallback的问题。
让我们看一看。正如我们所知,使用useCallback是为了获得更好的性能。
function MainScreen() {
const [email, setEmail] = useState("");
const [pwd, setPwd] = useState(""):
const onAuthenticate = useCallback(() => {
MyApi.authenticate(email, pwd);
}, [email, pwd]);
return <div>
<MyCustomButton onPress={onAuthenticate}>LOGIN</MyCustomButton>
</div>;
}在上面的示例中,让我们假设有两个输入电子邮件和密码,那么MyCustomButton将在电子邮件或密码更改时呈现。我试图使用useCallback来减少渲染的次数,但对我来说,它还不够好。
后来,我想出了一种方法,从依赖项中取出电子邮件和密码,并使用useRef保存电子邮件和密码的值。
function MainScreen() {
const [email, setEmail] = useState("");
const [pwd, setPwd] = useState(""):
const emailRef = useRef(email);
const pwdRef = useRef(pwd);
const onAuthenticate = useCallback(() => {
MyApi.authenticate(emailRef.current, pwdRef.current);
}, []);
useEffect(() => {
emailRef.current = email;
pwdRef.current = pwd;
}, [email, pwd]);
return <div>
<MyCustomButton onPress={onAuthenticate}>LOGIN</MyCustomButton>
</div>;
}使用这种方法,它会在每次电子邮件或密码更改时停止在MyCustomButton中渲染。
它在性能和成本上真的更好吗?你们觉得呢,伙计们?
感谢您的分享。
发布于 2019-12-11 15:49:38
我看到你的代码出现的问题不是useCallback的问题,而是useState的问题。
react中的一条经验法则(无论是否使用钩子)是状态对正在显示的内容有直接影响。如果修改状态,则意味着应该重新呈现组件。
这一基本原理使得您的组件在使用useState时可以重新呈现。React假设email和password会改变你的组件的外观,因此,每当你改变它们的一个值时,它就会被重新渲染。
如果您实际上没有在MyCustomButton中使用email和pwd,那么使用useRef而不是useState更有意义。
然而,您在第二个代码示例中使用它的方式并没有多大意义:您组合了useState和useRef,以便当email发生变化时(使用setEmail时就是这种情况),然后使用相同的值更新ref。您从中得到的唯一好处是onAuthenticate不会每次都被重构。
完全跳过useState会更有好处,但从您发布的代码来看,很难实际提出不同的解决方案,因为不清楚email和pwd实际上是如何/何时设置的。
发布于 2019-12-11 15:50:17
由于您只是在执行API调用,因此我建议不要使用 useCallback()。改为将其设置为普通函数。
您可能正在进行过早的优化。如果你在你的应用上执行繁重的计算,并且你需要记住你的值,你应该只做性能优化。
从here.可以看到普通函数与使用useCallback()的函数的深入比较
发布于 2019-12-11 16:03:45
在这种情况下,我希望使用React.memo而不是useCallback。使用React.memo确保一旦组件调用render、email或pwd发生更改,该组件将不会调用render cased by parent,因此useCallback是不必要的
function MainScreen() {
const [email, setEmail] = useState("");
const [pwd, setPwd] = useState(""):
const onAuthenticate = () => {
MyApi.authenticate(email, pwd);
};
return <div>
<MyCustomButton onPress={onAuthenticate}>LOGIN</MyCustomButton>
</div>;
}
export default React.memo(MainScreen)https://stackoverflow.com/questions/59280820
复制相似问题