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);
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>
);
}
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>
);
}
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
» npm install react-native-navigation-hooks
How to use react hooks on react-native with react-navigation
reactjs - React Native: Why not just use Navigation hooks all the time? - Stack Overflow
useNavigation hook from react navigation
how to create a hook with navigation properties for useContext react-native - Stack Overflow
Videos
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);
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>
);
}
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>
);
}
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
in order to share data between components you can use Context API or Redux, passing full objects through navigation routes is an anti-pattern, you can find more information in the docs
https://reactnavigation.org/docs/params/#what-should-be-in-params
» npm install react-navigation-hooks
hello, i have a multiple questions regarding useNavigation hook
is using this hook considered a good way to handle the navigation clicks between screens and custom components?
does it make the app laggy or will it throw some rendering errors?
like when you have a custom button inside of a screen or inside of a navigators (in App.js) and u want this button to go back or send u to other screen, is using this hook a good way to handle this type of thing?
i hope i made my questions clear.
I believe you need to wrap the Root component with the NavigationContainer. Once done, you can use the useNavigation hook in any child component. For instance inside the CommonProvider you can use the hook useEffect in that way.
const navigation = useNavigation();
useEffect(()=>{
navigation.navigate('YourNextScreenName')
}, [navigation])
I managed to solve it as follows: persist a file of routes/RootNavigation.ts
import { createNavigationContainerRef } from '@react-navigation/native';
export const navigationRef = createNavigationContainerRef();
export function navigate(name: string, params: any) {
if (navigationRef.isReady()) {
navigationRef.navigate(name,params);
}
}
in my case what contains the centralization of routes in the file add the navigationRef, no NavigationContainer: routes/index.tsx
...
<NavigationContainer linking={linking} independent ref={navigationRef}>
...
using in file any hook:
...
function handleMovePage() {
// navigation.navigate('SignIn');
RootNavigation.navigate('SelectArea', { userName: 'Lucy' });
}
...
reference: https://reactnavigation.org/docs/navigation-context/