React 功能组件在重新渲染时重新初始化局部函数和变量(React Hooks)
React functional component reinitialises local functions and variables on re render (React Hooks)
所以我现在开始使用 React hooks。我已经尝试 API 一段时间了。我真的很喜欢将状态带入功能组件的想法。但是有一件事一直困扰着我,当我尝试使用它时,我的直觉感觉不对。我尝试在 RFCs
上发帖,但现在那里太拥挤了。一切似乎都在那里丢失了。
这是我示例中的一段代码。
import React, { useState } from "react";
function Counter() {
const [counterState,incrementCounterState] = useCommontState(0);
function doSomething (){
// does something and then calls incrementCounterState
// with the updated state.
}
return (
<div>
<p>{counterState}</p>
<button onClick={incrementCounterState}>increase</button>
....
.... // some jsx calling local scoped functions.
....
</div>
);
}
function useCommontState(defaultValue){
var [state, setState] = useState(0);
function increment(){
setState(defaultValue+=1);
}
return [state, increment]
}
export default Counter;
我可以轻松取出 state
和 setState
方法并创建自定义 hook
但我的问题是组件使用的本地函数。由于状态现在是组件的一部分,因此在某些情况下,某些逻辑将决定下一步如何处理状态。
此外,当组件根据状态更改重新呈现时,所有内容都会重新初始化。这是我的问题。我知道 useState
有自己的处理方式。但我的问题是我自己的功能。点击处理程序。关于更改事件、子组件的回调等。每次组件呈现时都会重新初始化所有这些。这对我来说不合适。
有什么方法可以解决这个问题。这是一个新 API。我们甚至不确定它是否会变成 react 17
。但是有人遇到过更好的方法吗?
您始终可以通过将所需的值作为常量传递来简化代码以取出函数,这样它们就不会总是被初始化。
import React, { useState } from "react";
function doSomething (counterState, incrementCounterState){
// does something and then calls incrementCounterState
// with the updated state.
}
function Counter() {
const [counterState,incrementCounterState] = useCommontState(0);
return (
<div>
<p>{counterState}</p>
<button onClick={incrementCounterState}>increase</button>
....
.... // some jsx calling local scoped functions.
....
</div>
);
}
function increment(defaultValue, setState){
setState(defaultValue + 1);
}
function useCommontState(defaultValue){
var [state, setState] = useState(0);
return [state, increment]
}
export default Counter;
另外,在我看来,所有演示和文档中建议的功能设计都是为了让人们适应它,然后再考虑重新初始化方面。此外,重新初始化的成本将大大超过它提供的其他好处。
当我第一次看到该提案时,我也有同样的担忧,但这在 React Docs Hooks Proposal FAQ:
中得到了解决
Are Hooks slow because of creating functions in render?
No. In modern browsers, the raw performance of closures compared to classes doesn’t differ significantly except in extreme scenarios.
我的结论是,虽然现在在每次渲染的重复声明中有额外的开销,但您在其他地方有额外的收获:
Hooks avoid a lot of the overhead that classes require, like the cost of creating class instances and binding event handlers in the constructor.
Idiomatic code using Hooks doesn’t need the deep component tree nesting that is prevalent in codebases that use higher-order components, render props, and context. With smaller component trees, React has less work to do.
总的来说,好处可能多于使 hooks 值得使用的缺点。
我正在使用 createOnce
辅助函数来防止重新初始化,但我不确定它是否正确。
utils/createOnce.js
import { useMemo } from 'react';
export const createOnce = toCreate => useMemo(() => toCreate, []);
SomeComponent.js
...
const someFunction = createOnce((counter) => {
// whatever
return counter + 1;
});
...
所以我现在开始使用 React hooks。我已经尝试 API 一段时间了。我真的很喜欢将状态带入功能组件的想法。但是有一件事一直困扰着我,当我尝试使用它时,我的直觉感觉不对。我尝试在 RFCs
上发帖,但现在那里太拥挤了。一切似乎都在那里丢失了。
这是我示例中的一段代码。
import React, { useState } from "react";
function Counter() {
const [counterState,incrementCounterState] = useCommontState(0);
function doSomething (){
// does something and then calls incrementCounterState
// with the updated state.
}
return (
<div>
<p>{counterState}</p>
<button onClick={incrementCounterState}>increase</button>
....
.... // some jsx calling local scoped functions.
....
</div>
);
}
function useCommontState(defaultValue){
var [state, setState] = useState(0);
function increment(){
setState(defaultValue+=1);
}
return [state, increment]
}
export default Counter;
我可以轻松取出 state
和 setState
方法并创建自定义 hook
但我的问题是组件使用的本地函数。由于状态现在是组件的一部分,因此在某些情况下,某些逻辑将决定下一步如何处理状态。
此外,当组件根据状态更改重新呈现时,所有内容都会重新初始化。这是我的问题。我知道 useState
有自己的处理方式。但我的问题是我自己的功能。点击处理程序。关于更改事件、子组件的回调等。每次组件呈现时都会重新初始化所有这些。这对我来说不合适。
有什么方法可以解决这个问题。这是一个新 API。我们甚至不确定它是否会变成 react 17
。但是有人遇到过更好的方法吗?
您始终可以通过将所需的值作为常量传递来简化代码以取出函数,这样它们就不会总是被初始化。
import React, { useState } from "react";
function doSomething (counterState, incrementCounterState){
// does something and then calls incrementCounterState
// with the updated state.
}
function Counter() {
const [counterState,incrementCounterState] = useCommontState(0);
return (
<div>
<p>{counterState}</p>
<button onClick={incrementCounterState}>increase</button>
....
.... // some jsx calling local scoped functions.
....
</div>
);
}
function increment(defaultValue, setState){
setState(defaultValue + 1);
}
function useCommontState(defaultValue){
var [state, setState] = useState(0);
return [state, increment]
}
export default Counter;
另外,在我看来,所有演示和文档中建议的功能设计都是为了让人们适应它,然后再考虑重新初始化方面。此外,重新初始化的成本将大大超过它提供的其他好处。
当我第一次看到该提案时,我也有同样的担忧,但这在 React Docs Hooks Proposal FAQ:
中得到了解决Are Hooks slow because of creating functions in render?
No. In modern browsers, the raw performance of closures compared to classes doesn’t differ significantly except in extreme scenarios.
我的结论是,虽然现在在每次渲染的重复声明中有额外的开销,但您在其他地方有额外的收获:
Hooks avoid a lot of the overhead that classes require, like the cost of creating class instances and binding event handlers in the constructor.
Idiomatic code using Hooks doesn’t need the deep component tree nesting that is prevalent in codebases that use higher-order components, render props, and context. With smaller component trees, React has less work to do.
总的来说,好处可能多于使 hooks 值得使用的缺点。
我正在使用 createOnce
辅助函数来防止重新初始化,但我不确定它是否正确。
utils/createOnce.js
import { useMemo } from 'react';
export const createOnce = toCreate => useMemo(() => toCreate, []);
SomeComponent.js
...
const someFunction = createOnce((counter) => {
// whatever
return counter + 1;
});
...