React Native - Redux: multiple instances of the same state in an application

I am new to React Native. I use reduction for my responsiveness to the embedded application, however I am having a problem due to the global state of redux storage .

Suppose, for example, When moving forward in an application, I move as shown below. enter image description here

While going back

enter image description here

According to the redux architecture , it changes the state of each page instance present in the navigation stack, with the most recent state in the repository.

Here is the code for the above example

Page.js [Component]

class Page extends Component{ componentWillMount(){ } render(){ var {image,apiCall} = this.props; return ( <View> <Image Source={{uri:image}} style={{// style for the image}}> </View> )} componentDidMount(){ this.props.apiCall(this.props.route.data.link); // this.props.route.data.link -> this is just a link for // the apiCall } componentWillReceiveProps(){ } shouldComponentUpdate(nextProps, nextState){ if(this.props.image==nextProps.image){ return false; } return true; } componentWillUpdate(){ } componentDidUpdate(){ } componentWillUnmount(){ } } const mapStateToProps = (state) => { return { image: state.PageDataReducer.image }; }; const mapDispatchToProps = (dispatch) => { return { apiCall: (link) => { dispatch(fetchProduct(link)); // fetchProduct() -> is a function which fetches the product from the // network and dispatches the action. }, }; }; export default connect(mapStateToProps,mapDispatchToProps)(Page); 

fetchProduct () [Function to retrieve a product]

 export function fetchProduct(link) { return function(dispatch){ // fetches the product over network dispatch(fetchedProduct(productLink)); } } 

fetchedProduct [Action]

 export const fetchedProduct = (productLink) => { return { type: FETCHED_PRODUCT, image: image }; }; 

PageDataReducer [Reducer]

 export default function PageDataReducer(state = initialState, action) { switch (action.type) { case FETCHED_PRODUCT: var newState = { ...state, image: action.image }; return newState; default: return state; } } 

My observation . Whenever the same page appears in the navigation, and the state in the repository of this page receives changes, it calls mapStateToProps () of this page the number of times the page is in the navigation stack . And therefore, this is the number of times it goes through the lifecycle methods of this page to change state according to the last state.
In this example , when I click on the bananas in the box, it changes state from mango to banana in the repository and mapStateToProps () is called 3 times (because this page is present 3 times in the navigation stack) and, therefore, all the reaction lifecycle methods from componentWillReceiveProps () on componentDidUpdate () is called 3 times only to change the state of this page in accordance with the last state .

I want to . I want the navigation system to display a different page state. Therefore, returning, I see all the different products that I visited.

The problem is obvious according to the redux architecture, but I don't understand how to solve it. Any help or any other work around to achieve my goal would be greatly appreciated.

+5
source share
2 answers

You must separate the storage of your domain data, such as apple, mango and banana data, from the storage of your user interface state, for example, which item is currently selected. In the domain data part, you will save all the items that were once loaded (you can add some garbage collection policies later, such as at least recently used lists to save some memory).

Presentation components will then connect to both parts of the application state tree: the user interface part to get what is currently selected, and the domain part to get information about the selected item.

In your mapStateToProps function, the current selection is first extracted, it must be an identifier. You can also retrieve it from another place, for example. from props components (second argument to mapStateToProps). You then use this extracted identifier to retrieve already downloaded data from the domain data store. If the selected data is not in the repository (for example, when the user first visits the page or has already collected garbage), you put an empty value in the details, and this will mean that the hooks of componentDidMount or componentWillReceiveProps that they must fulfill the request to load data (this may be implemented as sending an action that signals the need for data for the saga or thunk, depending on what you use to control the loading of data), while this happens, the render return some β€œload ...” stubs. When the request is completed, another send will update the domain data store update, which will result in a connection to cause another call to mapStateToProps, and this will lead to the discovery that the selected data is already in the store, so a new request to load data will not be made, and the render will have enough data to display.

+1
source

What you are trying to do cannot be done only with Redux.

You need to historicize your changes in the browser or application in the form of navigation changes. HistoryJS is used for this. This module is used by react-router and offers good UX in web navigation.

So, use react-router to declare different pages (one for each fruit), or at least use HistoryJS to save the navigation state programmatically.

I don’t know how the router reacts to its own applications, so check out the React Native Router . It provides a way to handle navigation using Redux in a native application .

-1
source

Source: https://habr.com/ru/post/1258147/


All Articles