useEffect重新渲染太多次

时间:2020-01-06 02:44:59

标签: reactjs

我有这个组件,需要获取数据,将其设置为state,然后将其传递给子级。 一些数据也需要在上下文中设置。 我的问题是,使用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,
  ]);

...```




2 个答案:

答案 0 :(得分:3)

仅将一个空数组传递给useEffect的第二个参数。

注意

React保证setState函数身份稳定且不会 重新渲染。这就是为什么可以安全地忽略useEffect的原因 或useCallback依赖项列表。 Source

编辑:尝试使用this避免重新提交。谨慎使用

答案 1 :(得分:0)

仅在挂载和卸载上运行

您可以传递空数组[]的特殊值,以表示“仅在安装和卸载时运行”。因此,如果我们将上面的组件更改为像这样调用useEffect

useEffect(() => {
  console.log('mounted');
  return () => console.log('unmounting...');
}, [])

然后它将在初始渲染后打印“已安装”,在整个生命周期中保持沉默,并在输出时打印“正在卸载...”。

通过运行每个渲染器防止useEffect

如果您想减少效果的运行频率,可以提供第二个参数-值数组。将它们视为实现此效果的依赖项。如果自上次以来某个依赖项已更改,则效果将再次运行。 (它还将在初始渲染后运行)

const [value, setValue] = useState('initial');

useEffect(() => {
  // This effect uses the `value` variable,
  // so it "depends on" `value`.
  console.log(value);
}, [value])

更多说明useEffect