如何监听 React Native 中导航状态参数的变化?

Sen*_*ika 5 javascript navigation state react-native use-effect

我正在使用 React Native 开发移动应用程序。在那里,我在导航到第二页时传递了一些内容。

所以,假设我的第一个屏幕有这样的东西。

export default function firstScreen(props) {
  return(
    //data is a custom object variable that may be changed.
    <Button onPress={() => props.navigation.navigate('SecondScreen', { data: data } )} /> 
  )
}
Run Code Online (Sandbox Code Playgroud)

在我的第二个屏幕上,假设有这样的东西......

export default function secondScreen(props) {
  const { data } = props.navigation.state.params;

  useEffect(() => {
    console.log(data);
  }, [data])


  return(
    //content
  )
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,当data从第一个屏幕更改时,第二个屏幕不会监听该更改并data在控制台上打印变量的内容。

所以,我想知道,如何在React Native中监听导航状态的变化。

min*_*ist 5

以下是我如何在React Navigation V5 中使用hooks解决这个问题

import { useRoute } from '@react-navigation/native';
const route = useRoute();
useEffect(() => { //This will run whenever params change
     const {params = {}} = route;
    //your logic here
}, [route]);
Run Code Online (Sandbox Code Playgroud)


Gur*_*ran 2

您可以使用挂钩“useNavigationState”从第二个屏幕获取导航状态。

然后,您将再次遇到从第一个屏幕实际更新它的问题。当您传递参数时,它是导航状态的一部分,并且您对对象所做的更改不会反映在那里。

更新导航状态的一种方法是调度一个操作,但这将是一个问题,因为您需要找到要更新的屏幕的键。调度会是这样的

navigation.dispatch({ ...CommonActions.setParams({ data: {} }), 来源:route.key, });

由于您需要将对象的更新发送到另一个屏幕,因此您应该考虑诸如 React context 之类的内容,或者如果您的应用程序中已经有 redux,则可以在需要时使用它。

最简单的方法是反应上下文,您可以从一个屏幕更新并从另一个屏幕接收。

使用上下文的版本如下所示。这里使用一个简单的堆栈导航器,上下文从主屏幕更新,并且可以从设置屏幕读取值。您可以使用相同的方式更新数据变量并从另一个屏幕获取数据。这里我们不使用导航状态,但我们维护自己的变量上下文。

const Stack = createStackNavigator();
const CountContext = React.createContext({ count: 1, setCount: () => {} });

function HomeScreen({ navigation, route }) {
  const { count, setCount } = React.useContext(CountContext);
  React.useEffect(() => {
    const interval = setInterval(() => {
      setCount(count => count + 1);
    }, 1000);

    return () => {
      clearInterval(interval);
    };
  }, []);

  return (
    <View>
      <Text>Test{count}</Text>
      <Button
        title="Go to settings"
        onPress={() => navigation.navigate('Settings')}
      />
    </View>
  );
}

function SettingsScreen({ navigation, route }) {
  const { count, setCount } = React.useContext(CountContext);
  return (
    <View>
      <Text>Settings! {count}</Text>
      <Button title="Go back" onPress={() => navigation.goBack()} />
    </View>
  );
}

export default function App() {
  const [count, setCount] = React.useState(0);
  const value = { count, setCount };

  return (
    <CountContext.Provider value={value}>
      <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen name="Home" component={HomeScreen} />
          <Stack.Screen name="Settings" component={SettingsScreen} />
        </Stack.Navigator>
      </NavigationContainer>
    </CountContext.Provider>
  );
}
Run Code Online (Sandbox Code Playgroud)

你可以看看这个小吃 https://snack.expo.io/@guruparan/stateparamschange