如何使用 react-navigation 在 react-native 上使用 react hooks [英] How to use react hooks on react-native with react-navigation

查看:53
本文介绍了如何使用 react-navigation 在 react-native 上使用 react hooks的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是使用 react-navigation 的 App.js.它有两个屏幕,称为 HomeScreen 和 AddScreen.

This is App.js using react-navigation. There are two screens on it called HomeScreen and AddScreen.

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

import HomeScreen from './src/HomeScreen';
import AddScreen from './src/AddScreen';

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Add" component={AddScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

这是主屏幕.useState"中有一个items".它是通过 Add by navigation 作为 props 给出的.

And This is home Screen. There is a 'items' in 'useState. It is gived through Add by navigation as props.

import * as React from 'react';
import PropTypes from 'prop-types';
import { View, Text, Button } from 'react-native';


function HomeScreen({ navigation, route }) {
  const [items, setItems] = React.useState([]);

  React.useEffect(() => {
    if (route.params?.items) {
      // Post updated, do something with `route.params.post`
      // For example, send the post to the server
      console.log('saved');
    }
  }, [route.params?.items]);

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button
        title="Create post"
        onPress={() => navigation.navigate('Add', { items, setItems })}
      />
      <View>
        {items.map((item, i) => {
          return (
            <View>
              <Text>{item.itemName}</Text>
              <Text>{item.itemPrice}</Text>
            </View>
          );
        })}
      </View>
    </View>
  );
}

HomeScreen.propTypes = {
  navigation: PropTypes.object.isRequired,
};

export default HomeScreen;

AddScreen 接收items"作为 route.params.
它使用setItems"将自己的数据推送到其中.
添加后,导航返回主屏幕,其中包含添加新项目的项目.

And AddScreen receives 'items' as route.params.
And it use 'setItems' to push his own data in it.
After adding, navigation return to HomeScreen with items that is added with new item.

import * as React from 'react';
import PropTypes from 'prop-types';

import { View, Text, Button, TextInput } from 'react-native';

function AddScreen({ route, navigation }) {
  const { items, setItems } = route.params;
  const [itemName, setItemName] = React.useState('');
  const [itemPrice, setItemPrice] = React.useState('0');

  const addItem = () => {
    setItems([...items, { itemName, itemPrice }]);
    setItemName('');
    setItemPrice('0');
  };

  return (
    <View>
      <TextInput
        multiline
        placeholder="What's on your mind?"
        value={itemName}
        onChangeText={setItemName}
      />
      <TextInput
        multiline
        placeholder="What's on your mind?"
        value={itemPrice}
        onChangeText={setItemPrice}
      />
      <Button
        title="Done"
        onPress={() => {
          addItem();
          // Pass params back to home screen
          navigation.navigate('Home', items);
        }}
      />
    </View>
  );
}

AddScreen.propTypes = {
  navigation: PropTypes.object.isRequired,
  route: PropTypes.object.isRequired,
};

export default AddScreen;

它对我的目的很有效.
但我不确定这种方式是否正确使用反应钩子从父级到子级发送和接收数据.
你能修改我的代码吗?

It works well on my purpose.
But I'm not sure whether this way is correct or not using react hooks to give and receive data from parent to child.
Could you modify my code ?

推荐答案

你应该考虑使用 React Context API https://uk.reactjs.org/docs/context.html.它致力于共享公共状态(在您的情况下为 items).下面是一个例子:您应该为项目创建一个公共上下文:ItemsState.js

You should consider using React Context API https://uk.reactjs.org/docs/context.html. Its dedicated to sharing the common state (items in your case). Here is an example: You should create a common context for items: ItemsState.js

import React, { useState, useContext } from 'react';

const ItemsContext = React.createContext([]);

export const ItemsProvider = ({ children }) => {
  return (
    <ItemsContext.Provider value={useState([])}>
      {children}
    </ItemsContext.Provider>
  );
}

export const useItems = () => useContext(ItemsContext);

然后像这样在 App.js 中与提供者共享屏幕之间的上下文

Then share the context between screens with provider in App.js like this

import {ItemsProvider} from 'ItemsState';

function App() {
  return (
   <ItemsProvider> // share the items between both screens
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Add" component={AddScreen} />
      </Stack.Navigator>
    </NavigationContainer>
   </ItemsProvider>
  );
}

然后在每个屏幕中使用项目上下文,像这样 AddScreen.js

Then use items context in each screen like this AddScreen.js

import {useItems} from './ItemsState';

function AddScreen({ route, navigation }) {
  const [items, setItems] = useItems(); // <- using items context as global useState
  const [itemName, setItemName] = React.useState('');
  const [itemPrice, setItemPrice] = React.useState('0');

  const addItem = () => {
    setItems([...items, { itemName, itemPrice }]);
    setItemName('');
    setItemPrice('0');
  };

  return (
    <View>
      <TextInput
        multiline
        placeholder="What's on your mind?"
        value={itemName}
        onChangeText={setItemName}
      />
      <TextInput
        multiline
        placeholder="What's on your mind?"
        value={itemPrice}
        onChangeText={setItemPrice}
      />
      <Button
        title="Done"
        onPress={() => {
          addItem();
          // Pass params back to home screen
          navigation.navigate('Home', items);
        }}
      />
    </View>
  );
}

你也可以使用 useReducer 钩子来制作更像 Redux 的东西.看看这篇文章https://medium.com/simply/state-management-with-react-hooks-and-context-api-at-10-lines-of-code-baf6be8302c

You can also use useReducer hook and make more Redux-like. Check out this article https://medium.com/simply/state-management-with-react-hooks-and-context-api-at-10-lines-of-code-baf6be8302c

这篇关于如何使用 react-navigation 在 react-native 上使用 react hooks的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆