react native - send update/data to previous screen via current screen - react-native

So my first screen, say ParentScreen has a FlatList of a component. When any component of the list is clicked, it opens another screen ChildScreen. Now what I'm trying to do is that when I perform an action on the ChildScreen, the ParentScreen's FlatList needs to be updated.
I'm using react-native-navigation, so my current approach is to send props via passProps property via this.props.navigator.push() but when I perform an action on the ChildScreen, it's unable to update that data because the ParentScreen is frozen at that time, hence it gives me the error:
You attempted to set the key count with the value 3 on an object
that is meant to be immutable and has been frozen.
How can I communicate this data OR do a workaround to allow the same.

You need to read about react-redux, with that you can manage your states and pass data from one componet to the other by mapping states to props, you will learn about reducers, combine reducers and actions.
this youtube link can help you alot https://www.youtube.com/watch?v=ucd5x3Ka3gw

Related

How to pass state from one react native screen to another

I have two independent screen
Login Screen
DashBoard
Now on the login screen i store the requested API data inside the state (this.state.data) and that stored data I want to show on the dashboard screen for example the name or the age or the country or whatever. Now how do I sync both of these screens, I am using React Navigation 2.0
On success of a login request you need to change your current component to the Dashboard component, which -
Can be done in two ways
If you are replacing the component then you can call <Dashboard data={this.state.data} /> and fetch it in your Dashboard screen as this.props.data
If you are navigating to the component, you can do it via this.props.navigation.navigate('Dashboard', { data: this.state.data }); and then in your Dashboard component you can fetch it via this.props.navigation.state.params.data
Hope it helps :)
If you are doing a small project, you can do this via props, as explained by #Aseem Upadhyay
But note that this method becomes ineffective as your project grows. Imagine that you have multiple screens, distributed in a hierarchy, in which one daughter screen needs to pass data to another, which is on a different node. To do this via props, it would be necessary for the parent component to pass these values ​​to both screens. This form is very difficult to manage.
The ideal way to do this is through redux. With it, you create a shared store of variables, so you can access them anywhere in the application. The following link demonstrates how to configure redux in your project.
https://blog.cloudboost.io/getting-started-with-react-native-and-redux-6cd4addeb29
It is recommended to use redux for variables that need to be shared. If you have only local component variables, then you do not need to use it.
I hope this can help you in your projects.
Hugs!

React Native: How to trigger remote fetch when switching back to tab based on state

I am building an app with 2 tabs (react-navigation). I am new to react and redux and I am still trying to wrap my head around how to communicate between components without creating too many unnecessary dependencies.
Tab A: The main component is fetching data via a remote API. For this I am using a react-redux and redux-thunk. The data is kept inside the central store since it is used for button states across different components (Tab A and Tab B). Pressing a button is calling a Thunk that deals with the asynchronous API call to update the server and then dispatches the action to update the store.
Tab B: Also fetches its data via a remote API but sets it via the component's State. I did not see the point of also putting this into the redux store since it is not shared across components. The button component from Tab A is also used here.
What I am trying to achieve: When the state inside the redux store changes (button's onPress() dispatches an action) both Tab A and Tab B require to re-fetch via the remote API but only under the following circumstances:
Switching from one tab to the other requires a re-fetch inside the target tab. Then, only when switching back to the first tab it should also trigger a re-fetch.
What I considered:
Adding a tabAinvalidated and tabBinvalidated flag to the redux store. I then listen to the willFocus event inside both tabs. I then re-fetch if the respective tab is flagged as invalidated. This might work but I am not sure if it is considered an anti-patter to keep update flags for individual components inside the redux store.
Q: Is there a better approach to this? What is the best way in react native to inform components that they need to reload their data from a remote API?
I think I came up with a solution myself. Instead of using the boolean flags for each tab (tabAinvalidated, tabBinvalidated) I am now just recording a timestamp for every update inside the redux store. For components which require re-fetching based on redux store updates I copy the redux timestamp into their own component's State each time I re-fetch the data. This way I can check if the component needs to re-fetch its own data from the server.
setFocus = async() => {
if (this.props.updateTs > this.state.updateTs) {
await this.loadData()
this.setState({ updateTs: this.props.updateTs, })
}
}
Seems to work fine.

React Native - FlatList - Internal State

I'm using a FlatList in order to implement a Store View in my react-native app.
I'm retrieving the store items from an API Call that is done in the componentDidMount cycle step of my component and then store it in my local state.
I've found in the Flatlist documentation this sentence :
Internal state is not preserved when content scrolls out of the render window. Make sure all your data is captured in the item data or external stores like Flux, Redux, or Relay.
I was wondering what it meant. I'm just using my local state and it seems to work just fine.
Is there any issue by doing so ? Could you provide me more informations about this particular point ?
Also, if you have any advice or optimization about my use-case, feel free to add them.
Thanks for your time.
Let's say you have a Contacts component with a FlatList rendering Contact component for each item in your data. Let's also say that these contacts are selectable. If you store these select value ( for example selected: true) in Contact components internal state and not in Contacts components state, when the item scrolls out its going to be unmounted and the state of that item going to be reset. If you hold it in the global data it will be created with the last state.
Hope I was able to explain.

Vuejs: shared states between components

I would like to know the best practice for implementing shared states between components in Vuejs.
Imagine situation A: you have a web app that shows a modal. The modal has the boolean state show. This state should change if the modal OK-button is clicked, but also if any part of the background is clicked, and perhaps even on some server pushed state change. Thus the modal should be able to change the state as should the parent app.
Situation B: you have a web app that shows input fields inside different components that share a common data value. If the user changes value through the field in one component, it should also update in the other. Again both should even update on a server push event.
Questions:
I am right that the correct way to go about this would be to use vuex and make the shared state a store field that is observed by and changed through emitted actions by all components / parents that need to modify that value?
Does that not introduce this kind of dangerous (since hard to handle) magic reactivity that we know from Meteor?
How to best document the flow, what depends on what?
A: For a modal component, I'd say that show should be a prop. So the parent component can control the modal whatever it wants. In this case there is no shared state at all.
The modal itself doesn't need to know anything about the server. If the prop show is true, just display the modal and vice versa.
I think the mask layer is a part of the modal, so when the mask is clicked, the modal emits an event. The parent component receives the event and can decide to hide the modal or not to.
Vue has an official modal example here (thanks #craig_h for mentioning): https://v2.vuejs.org/v2/examples/modal.html
B: Just bind the vuex state to the inputs. Nothing wrong.
Note that not all the components need to access the vuex store directly. For some pure UI components, just use props. So the parent components have the right to control them and increase flexibility.
I recommend you to read these docs:
https://facebook.github.io/react/docs/lifting-state-up.html
https://medium.com/#dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.j7ry4a3as
http://redux.js.org/docs/basics/UsageWithReact.html
Yes these are React / Redux docs. Since Vue is relatively young, react community has more documentation / articles. But both Vue and React are component-based libraries. The idea of how you design a component is basically the same.
You can also take a look at this vuex example: https://github.com/vuejs/vuex/tree/dev/examples/chat
This is a very simple example but it does use all the things I mentioned above. Emitting an event, some pure UI components...

Am i implementing redux correctly in my ReactNative app?

I am implementing a mobile application using ReactNative with Redux, the app that i am implementing looks like that:
Login (screen)
|--> Search for an object (screen)
|--> Show that object and edit it (screen)
|--> Take 2 photos (each photo a screen)
|--> A last screen for make a new object and save it
The above flow shows how each screen do their work and pass to the next screen.
My application state is the next:
{
auth: {
logged: false,
token: ''
},
somethingOfSideBar...
}
But i feel i am doing the things in the wrong way, because most of the screens have their own state, by example searchSomethingScreen fetch data from the server, check if it is valid and enable to pass to the next screen. I feel i am not doing the things in the Redux way, it suppose to make actions that change the entire state application, but i feel i do not need more state than i have. For me the global things are auth data and sidebar (because it is present across the entire application).
Should i make actions for every screen change?
Should i put more information in the global state application?
A one more thing, i have a AppContainer component which is used in connect to have access to the store, but i am passing parts of the state and the actions as well as children properties and i feel this is wrong as well.
I feel the Redux Reddit tutorial may be useful to you. It certainly was for me.
But i feel i am doing the things in the wrong way, because most of the screens have their own state, by example searchSomethingScreen fetch data from the server, check if it is valid and enable to pass to the next screen.
Used in the Redux way, API requests and their successful completion should each map to one action. Change the application state appropriately (in your reducing function) on each action and views/screens bound to your store will re-render. So if you're making an API request:
Create a Search container, mapping state searchResults to props and binding a Search component. (For example, see this container.)
Fire action REQUEST_SEARCH with search term on user input.
AJAX request is fired.
AJAX request successfully completes. Fire action RECEIVE_SEARCH with search results.
SearchReducer stores search results.
Bound Search component re-renders with search results.
Should i make actions for every screen change? Should i put more information in the global state application?
As a general rule, yes. But sometimes I've used component state (without dispatching an action) to store state that is local to the component (e.g. updating a text field).
A one more thing, i have a AppContainer component which is used in connect to have access to the store, but i am passing parts of the state and the actions as well as children properties and i feel this is wrong as well.
In general, higher level components should be containers, which inject state into the stateless components via props. You can have more than one containers and they work like components, so you can nest a container in another container. I encourage you to have a look at the docs, as it was very useful for me. :)