如何使用 react-navigation 在 react-native 上使用 react hooks [英] How to use react hooks on react-native with react-navigation
问题描述
这是使用 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屋!