How to setParams using useEffect and avoid getting infinty renderings?

北城余情 提交于 2021-01-02 06:04:05

问题


I'm using react-navigation and I have a dynamic header, so I'm using setParams and getting it in the title.

const MyComponent = ({navigation}) => {
    useEffect(() => {
        const { setParams, state } = navigation
        const { params = {} } = state
        const { description } = params
        setParams({ headerTitle: description })
    }, [])

    return (...)
}

MyComponent.navigationOptions = ({ navigation }) => ({
    title: navigation.getParam('headerTitle')
})

The problem here is that I only want to setParams once (so I use []) but I get a warning (eslint(react-hooks/exhaustive-deps)) and says that I need to add navigation to the dependency array.

If I add navigation to the dependency array, it will become a infinty loop.

setParam updates => navigation call => setParam updates => navigation and continues...

How can I call setParam only once and avoid do it correctly accordingly to react rule of hooks?


回答1:


Could useRef solve this as suggested at the bottom this answer?

import React, { useRef, useEffect } from 'react';

const MyComponent = ({ navigation }) => {
  const { state } = navigation;
  const { params = {} } = state;
  const description = useRef(params.description);
  const setParams = useRef(navigation.setParams);

  useEffect(() => {
    setParams.current({ headerTitle: description.current });
  }, [description, setParams]);

  return (...);
}

MyComponent.navigationOptions = ({ navigation }) => ({
    title: navigation.getParam('headerTitle')
})

I've not tested this but it looks like it should work.

For reference here are the useRef docs.




回答2:


I'm a year late to the party but... as far as I can tell, when setParams is called, navigation is updated, and so the component will re-render. If navigation is part of the dependency array, the useEffect will run again too. The trick is to run setParams conditionally based on the current nav params. In your case:

    useEffect(() => {
        const { setParams, state } = navigation
        const { params = {} } = state
        const { description, headerTitle } = params
        if (description !== headerTitle) {
            setParams({ headerTitle: description })
        }
    }, [navigation])

It's a little strange though that you're updating nav params with a value that is also a nav param. It seems simpler to just directly use it:

MyComponent.navigationOptions = ({ navigation }) => ({
    title: navigation.getParam('description')
})


来源:https://stackoverflow.com/questions/57019318/how-to-setparams-using-useeffect-and-avoid-getting-infinty-renderings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!