【发布时间】:2020-04-23 15:24:57
【问题描述】:
我有这个组件,它需要获取数据,将其设置为状态,然后将其传递给孩子。 一些数据也需要在上下文中设置。 我的问题是使用 useEffect,一旦调用 API,它将为我需要执行的每个 setvalue() 函数重新渲染。 我尝试将一个空的 [] 数组传递给 useEffect,但由于状态正在发生变化,因此仍然获得相同数量的重新渲染。 目前该数组包含 set...functions 以防止 eslint 引发警告。
有没有更好的方法来避免这么多的重新渲染?
const Home = (props) => {
console.log("TCL: Home -> props", props);
const classes = useStyles();
const [value, setValue] = React.useState(0);
//CONTEXT
const { listSavedJobs, setListSavedJobs, setIsFullView} = useContext(HomeContext);
const {
setUserName,
setUserLastName,
setUserEmail,
setAvatarProfile,
} = useContext(UserContext);
// STATE
const [searchSettings, setSearchSettings] = useState([]);
const [oppData, setOppData] = useState([]);
const handleChange = (event, newValue) => {
setValue(newValue);
};
const handleChangeIndex = index => {
setValue(index);
};
//API CALLS
useEffect(() => {
const triggerAPI = async () => {
setIsFullView(false);
const oppResponse = await API.getOpportunity();
if(oppResponse){
setOppData(oppResponse.response);
}
const profileResponse = await API.getUserProfile();
if(profileResponse){
setUserName(profileResponse.response.first_name);
setUserLastName(profileResponse.response.last_name);
setUserEmail(profileResponse.response.emailId);
}
const profileExtData = await API.getUserProfileExt();
if(profileExtData){
setAvatarProfile(profileExtData.response.avatar);
setListSavedJobs(profileExtData.response.savedJobs);
setSearchSettings(profileExtData.response.preferredIndustry);
}
};
triggerAPI();
}, [
setOppData,
setUserName,
setUserLastName,
setUserEmail,
setAvatarProfile,
setListSavedJobs,
setIsFullView,
]);
...```
【问题讨论】:
-
stackoverflow.com/a/53048903/9787887 如果状态更改是异步触发的(例如包装在 promise 中),它们将不会被批处理;。您可能在
async函数中使用了过多的set,每个set都会导致您重新渲染,这太多。不知道你说的too much是指too much还是infinite? -
如果
API.getOpportunity()、API.getUserProfile()和API.getUserProfileExt()是3个独立的api调用,表示结果会异步出来,那么没关系 为 3 次 api 调用 (但在你的可能是 8 次) 重新渲染 3 次(每个结果的每个重新渲染都有)?你的意思是太多的重新渲染是多少? -
有一些问题:如果
setUserName、setUserLastName、setUserEmail总是被设置在一起,你应该只使用一个名为user的状态对象 而不是 3 个状态变量userName、userLastName、userEmail,在这种情况下,它将为您节省 2 次重新渲染。另一个问题是您使用await的方式会导致 3 个 api 调用同步运行而不是并行运行,它不会导致更多的重新渲染,但会花费您更多的性能,修复您需要Promise.all。 -
@LoiNguyenHuynh 谢谢你,这些是我要实施的非常宝贵的建议。
标签: reactjs