我有这个组件,需要获取数据,将其设置为状态,然后传递给子组件。其中一些数据还需要设置在上下文中。我的问题是,使用useEffect一旦调用API,它就会为我需要执行的每个setvalue()函数重新渲染。我已经尝试向useEffect传递一个空[]数组,但由于状态正在改变,仍然会得到相同数量的重新渲染。目前,该数组包含set...函数以防止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,
]);
...```
set
,每个set
都会导致重新渲染,这太多了。我不知道你说的“太多”是指“太多”还是“无限”? - Loi Nguyen HuynhAPI.getOpportunity()
,API.getUserProfile()
和API.getUserProfileExt()
是3个独立的API调用,这意味着结果将异步返回,那么为了获取3个API调用的结果,重新渲染3次(每次重新渲染都是为了获取一个结果)是可以接受的(但在你的情况下可能是8次)?你所说的太多的重新渲染是多少? - Loi Nguyen HuynhsetUserName
,setUserLastName
,setUserEmail
总是一起设置,那么你应该使用只有一个状态对象叫做user
**而不是3个状态变量userName
,userLastName
,userEmail
**,这样可以在这种情况下节省2次重新渲染。另一个问题是你使用await
的方式会导致3个API调用同步运行而不是并行运行,这不会导致更多的重新渲染,但会花费更多的性能,要解决这个问题,你需要使用Promise.all
。 - Loi Nguyen Huynh