使用 useMemo 在渲染期间更新 React Hooks 状态
Update React Hooks State During Render Using useMemo
可以使用 useMemo
只是 来避免额外的引用相等性检查 code/vars 在设置状态 during 时使成为?
示例:useMemo
setState
在渲染期间取自此 rare documented use case:
function ScrollView({row}) {
let [isScrolling, setIsScrolling] = useState(false);
const lessCodeThanCheckingPrevRow = useMemo(
() => {
// Row changed since last render. Update isScrolling.
setIsScrolling(true); // let's assume the simplest case where prevState isn't needed here
},
[row]
);
return `Scrolling down: ${isScrolling}`;
}
以上大大减少了代码和额外的变量,仅用于相等性检查,那么为什么文档暗示引用相等性检查应该手动完成?
为此行为使用 useEffect 挂钩。 useMemo 用于存储一个值,该值不一定会在每次渲染时发生变化,这样您就可以避免对该值进行无用的重新计算
这对我来说似乎是一种减少样板文件的优雅方式。我创建了一个 codesandbox 来验证它的行为。
const UnitUnderTest = ({prop}) => {
let [someState, setSomeState] = useState(false);
const lessCodeThanCheckingPrevRow = useMemo(
() => setSomeState(current => !current),
[prop],
);
useEffect(() => console.log('update finished'), [prop])
console.log('run component');
return `State: ${someState}`;
}
const App = () => {
const [prop, setProp] = useState(false);
const handleClick = () => setProp(current => !current);
return (
<div>
<button onClick={handleClick} >change prop</button>
<UnitUnderTest prop={prop} />
</div>
)
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
点击按钮更改传递给组件的 prop 时的输出:
> run component
> run component
> update finished
如您所见,组件在更新周期完成之前已经 运行 两次。这等同于 getDerivedStateFromProps
.
的行为
我想没有更深入的思考为什么文档提出了一种略有不同的技术。在某种程度上,这也是一种手动检查,但方式很简洁。 +1 这个想法。
可以使用 useMemo
只是 来避免额外的引用相等性检查 code/vars 在设置状态 during 时使成为?
示例:useMemo
setState
在渲染期间取自此 rare documented use case:
function ScrollView({row}) {
let [isScrolling, setIsScrolling] = useState(false);
const lessCodeThanCheckingPrevRow = useMemo(
() => {
// Row changed since last render. Update isScrolling.
setIsScrolling(true); // let's assume the simplest case where prevState isn't needed here
},
[row]
);
return `Scrolling down: ${isScrolling}`;
}
以上大大减少了代码和额外的变量,仅用于相等性检查,那么为什么文档暗示引用相等性检查应该手动完成?
为此行为使用 useEffect 挂钩。 useMemo 用于存储一个值,该值不一定会在每次渲染时发生变化,这样您就可以避免对该值进行无用的重新计算
这对我来说似乎是一种减少样板文件的优雅方式。我创建了一个 codesandbox 来验证它的行为。
const UnitUnderTest = ({prop}) => {
let [someState, setSomeState] = useState(false);
const lessCodeThanCheckingPrevRow = useMemo(
() => setSomeState(current => !current),
[prop],
);
useEffect(() => console.log('update finished'), [prop])
console.log('run component');
return `State: ${someState}`;
}
const App = () => {
const [prop, setProp] = useState(false);
const handleClick = () => setProp(current => !current);
return (
<div>
<button onClick={handleClick} >change prop</button>
<UnitUnderTest prop={prop} />
</div>
)
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
点击按钮更改传递给组件的 prop 时的输出:
> run component
> run component
> update finished
如您所见,组件在更新周期完成之前已经 运行 两次。这等同于 getDerivedStateFromProps
.
我想没有更深入的思考为什么文档提出了一种略有不同的技术。在某种程度上,这也是一种手动检查,但方式很简洁。 +1 这个想法。