首页 > 解决方案 > React Native useEffect Hooks 和 React Navigation setParams 在加载时不会更新

问题描述

为什么我的 React Navigation setParams 不更新已安装组件的数据?

const NewScreen = props => {
  const [extraInfo, setExtraInfo] = useState({
    title: '',
    description: '',
  });
  const [mediaArray, setMediaArray] = useState(null);
  const [someData, setSomeData] = useState({});

  const grabData = useCallback(() => {
    return axios
      .get('url')
      .then(res => {
        /* does some data grabbing for setSomeData and setMediaArray */

        setSomeData({
          data1,
          data2,
          data3,
        });
        setMediaArray(media);
      })
      .catch(err => console.log('axios catch err', err));
  }, []);

  /* ... more data grabbing for extraInfo */

  useEffect(() => {
    grabData();
    props.navigation.setParams({
      mutate: props.mutate,
      title: extraInfo.title,
      description: extraInfo.description,
      newDataForAray: mediaArray,
      ...someData,
    });
  }, [grabData]);

  return (
    <KeyboardAvoidingView behavior="padding" style={styles.keyboardView}>
      ...
    </KeyboardAvoidingView>
  );
};

NewScreen.navigationOptions = props => {
  const {mutate, title, description, newDataForAray} = props.navigation.state.params;
  const handleSubmit = () => {
    mutate({
      variables: {
        title,
        description,
      },
    });
  };
  return {
    headerRight: () => (
      <TouchableOpacity
        onPress={() => handleSubmit()}
        style={{marginRight: 10}}>
        <Text>Done</Text>
      </TouchableOpacity>
    ),
  };
};

const mutation = gql`
  mutation someMutation(
    ...
  ) {
    ...
  }
`;

export default graphql(mutation)(withNavigation(NewScreen));

所以在加载时,我可以通过axios. 但是当组件安装时,其中的数据prop.navigation.setParams不会被填充。如果我将someData, mediaArray or extraInfo, 添加到 useEffect 回调的数组中,它将无限循环,重新渲染我的组件,但navigation.state最终会填充其中的数据。

我希望能够将值传递到导航状态,以便可以在标题中使用它

标签: reactjsreact-nativereact-hooksreact-native-navigationuse-effect

解决方案


使用您当前的设置,将提取您的数据,但在下一次渲染之前grabData不会刷新someData,等。mediaArray但是,你的下一个渲染不会运行,因为你的 useEffect 的依赖数组不会触发。

您可以使用两个useEffects,一个保留用于grabData,另一个用于props.nav。更好的是,props.navgrabData.


更新反映评论

媒体或某些数据值不会立即更改。因此,将您的 api 提取的相同媒体或某些数据引用到您的 setParams

 const grabData = useCallback(() =>
  axios
  .get('url')
  .then(res => {
    /* does some data grabbing for setSomeData and setMediaArray */

    const someData = {
      data1,
      data2,
      data3,
    };
    setSomeData(someData);
    setMediaArray(media);
    const paramsTest = {
       mutate: props.mutate,
       title: extraInfo.title,
       description: extraInfo.description,
       newDataForAray: media,
       ...someData,
     };
     console.log({ paramsTest }); // used to confirm values provided to nav
     props.navigation.setParams(paramsTest);
  })
  .catch(err => console.log('axios catch err', err)), [props.navigation.setParams]);

推荐阅读