使用 React native 和 React 导航进行数据管理和回调函数

Data management and callback functions with React native and React navigation

我正在尝试编写一个移动应用程序来学习 React Native。这是一个非常简单的应用程序,可以使用 API 调用显示预定义城市的当前天气。在这里您可以看到该应用程序的一些屏幕截图。

HomeScreen View, UserSettings View

使用带有选项卡导航器的反应导航,我希望有一个视图(主屏幕)显示 API 调用的结果(这里没问题),另一个可以 编辑城市列表(添加或删除城市)。

我的问题是正确管理数据。 我通常使用 react 在组件之间传递信息和回调函数,但由于使用了 react-navigation,这里看起来有点复杂。

使用 tabNavigator 我不能使用导航选项在组件之间传递信息所以我使用 initialParams。但是对于回调函数,我遇到了一些麻烦,例如“在导航状态中发现了不可序列化的值”。

对于这种情况,管理数据和回调函数的最佳做法是什么?

这里是代码的简化版本:

export default function App() {
      const [cityList, setCityList]=useState(["city1","city2","city3"]);
    
      const addCityToList =function(cityName){
        setCityList((oldCityList)=>{return([...oldCityList,cityName])})
      }
    return(
      <NavigationContainer>
        <Tab.Navigator initialRouteName="Home">
          {/**HomeScreen -> Display current weather for cities defined in UserSettings */}
          <Tab.Screen 
            name="Home" 
            component={HomeScreen} 
            initialParams={{ cityList:cityList}}/>
          
          {/*UserSettings -> View to add / remove cities */}
          <Tab.Screen 
            name="Settings" 
            component={UserSettings} 
            initialParams={
              { cityList:cityList, 
                addCityToList:addCityToList}
            } />
        </Tab.Navigator>
      </NavigationContainer>
    )
      }

您可以使用 Context 的全局状态,如下所示。


export const CityContext = React.createContext();

export default function App() {
  const [cityList, setCityList]=useState(["city1","city2","city3"]);
    
  const addCityToList = React.useCallback((cityName) => {
      setCityList((oldCityList)=>{return([...oldCityList,cityName])})
  }, [setCityList])

  return (
    <CityContext.Provider value={{cityList, addCityToList}}>
       <NavigationContainer>
        <Tab.Navigator initialRouteName="Home">
          <Tab.Screen 
            name="Home" 
            component={HomeScreen} />
          <Tab.Screen 
            name="Settings" 
            component={UserSettings} />
        </Tab.Navigator>
      </NavigationContainer>
    </CityContext.Provider>
  )
}

然后,如下使用。

const UserSettings = (props) => {
    const { cityList, addCityToList } = React.useContext(CityContext);

    ...

    return (...)
}

然后,在 HomeScreen 中对状态变化做出反应。

const HomeScreen = (props) => {
    const { cityList, addCityToList } = React.useContext(CityContext);
    
    // if you want to do something different, you could do it here
    useEffect(() => {
        // this is triggered, when the state cityList is updated
    }, [cityList])

   return (...)
}

备注:我上面加的useEffect是可选的。尽管如此,状态 cityList 还是会更新,如果您只想渲染更新后的城市,则无需执行任何其他操作。