Ard*_*adi 7 performance setstate reactjs react-state-management react-hooks
假设我有以下代码:(太冗长了)
function usePolicyFormRequirements(policy) {
const [addresses, setAddresses] = React.useState([]);
const [pools, setPools] = React.useState([]);
const [schedules, setSchedules] = React.useState([]);
const [services, setServices] = React.useState([]);
const [tunnels, setTunnels] = React.useState([]);
const [zones, setZones] = React.useState([]);
const [groups, setGroups] = React.useState([]);
const [advancedServices, setAdvancedServices] = React.useState([]);
const [profiles, setProfiles] = React.useState([]);
React.useEffect(() => {
policiesService
.getPolicyFormRequirements(policy)
.then(
({
addresses,
pools,
schedules,
services,
tunnels,
zones,
groups,
advancedServices,
profiles,
}) => {
setAddresses(addresses);
setPools(pools);
setSchedules(schedules);
setServices(services);
setTunnels(tunnels);
setZones(zones);
setGroups(groups);
setAdvancedServices(advancedServices);
setProfiles(profiles);
}
);
}, [policy]);
return {
addresses,
pools,
schedules,
services,
tunnels,
zones,
groups,
advancedServices,
profiles,
};
}
Run Code Online (Sandbox Code Playgroud)
当我在我的函数组件中使用这个自定义 Hook 时,getPolicyFormRequirements解析后,我的函数组件重新渲染9时间(我调用的所有实体的计数setState)
我知道这个特定用例的解决方案是将它们聚合成一个状态并调用setState一次,但是我记得(纠正我,如果我错了)在事件处理程序(例如onClick)上调用多个连续的setStates,事件处理程序完成执行后只发生一次重新渲染。
有没有什么方法可以告诉我React,或者React知道自己,在setState另一个setState出现之后,所以跳过重新渲染,直到你找到一秒钟的呼吸。
我不是在寻找性能优化技巧,而是想知道上述(粗体)问题的答案!
还是你觉得我想错了?
谢谢!
更新 我如何检查我的组件呈现 9 次?
export default function PolicyForm({ onSubmit, policy }) {
const [formState, setFormState, formIsValid] = usePgForm();
const {
addresses,
pools,
schedules,
services,
tunnels,
zones,
groups,
advancedServices,
profiles,
actions,
rejects,
differentiatedServices,
packetTypes,
} = usePolicyFormRequirements(policy);
console.log(' --- re-rendering'); // count of this
return <></>;
}
Run Code Online (Sandbox Code Playgroud)
And*_*orn 10
我想我应该在这里发布这个答案,因为它还没有被提及。
有一种方法可以强制批量进行状态更新。请参阅这篇文章以获取解释。下面是一个功能齐全的组件,无论 setValues 函数是否异步,它都只渲染一次。
import React, { useState, useEffect} from 'react'
import {unstable_batchedUpdates} from 'react-dom'
export default function SingleRender() {
const [A, setA] = useState(0)
const [B, setB] = useState(0)
const [C, setC] = useState(0)
const setValues = () => {
unstable_batchedUpdates(() => {
setA(5)
setB(6)
setC(7)
})
}
useEffect(() => {
setValues()
}, [])
return (
<div>
<h2>{A}</h2>
<h2>{B}</h2>
<h2>{C}</h2>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
虽然“不稳定”这个名称可能令人担忧,但 React 团队之前建议在适当的情况下使用此 API,而且我发现它对于减少渲染数量而不堵塞我的代码非常有用。
如果状态更改是异步触发的, React则不会批量更新您的多个状态。例如,在您的情况下,因为您在解析 policiesService.getPolicyFormRequirements(policy) 后调用 setState,react 不会对其进行批处理。
相反,如果它只是以下方式,React 将批处理 setState 调用,在这种情况下,将只有 1 次重新渲染。
React.useEffect(() => {
setAddresses(addresses);
setPools(pools);
setSchedules(schedules);
setServices(services);
setTunnels(tunnels);
setZones(zones);
setGroups(groups);
setAdvancedServices(advancedServices);
setProfiles(profiles);
}, [])
Run Code Online (Sandbox Code Playgroud)
我在网上找到了下面的代码和框示例,它演示了上述两种行为。
https://codesandbox.io/s/402pn5l989
如果您查看控制台,当您点击“with promise”按钮时,它会首先显示 aaa 和 bb,然后是 a aa 和 b bb。
在这种情况下,它不会立即渲染 aa - bb,每次状态更改都会触发新的渲染,没有批处理。
但是,当您单击“无承诺”按钮时,控制台会立即显示 a aa 和 b bb。因此,在这种情况下,React 会批量处理状态更改,并同时为两者进行一次渲染。
| 归档时间: |
|
| 查看次数: |
6568 次 |
| 最近记录: |