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.
Related
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!
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
I am using react-native, nested react-navigation, SectionLists, ActionSheet, etc and I am having hard times setting up a decent way of refreshing components / screens. As I have a few different cases, I have also tried different approaches with no luck.
Examples:
- Sending a callback function as a param in the navigator when transitioning from one screen to another for state change.
- Assigning AsyncStorage.getItem straight to a state variable (e.g: used on a ListView) and expect it to refresh.
I've seen many questions in the react-navigation git repo (mainly on how to refresh a screen), and recent suggestion to the project on the best approach for future releases, that got me asking if this is something that is in place already.
I can say though, that I've successfully used redux to check the connection state (NetInfo), that although I couldn't yet port the same idea to a different schenario, I think that it is my best approach.
At the moment I have one schenario, that if solved, I believe will answer a few questions I have. For example:
I have a list of news in my Home screen and a few options in my Drawer navigator that I would like to, when clicked, to sort the Home list, without having to call navigate('screen_name') as I would like to, to still keep the Drawer opened after clicked.
What would be the best approach for this ?
Thanks in advance!
One approach you could follow is:
On click on a DrawerNavigator item, you can dispatch an action which would intern change the state by a value. Eg: filterBy: . This store value can be passed as a prop to your home screen, which would intern contain a logic to filter based on that value.
I havent worked with DrawerNavigator but i feel onPress on each item in drawer navigation can be prevented and a action can be invoked at the same place.
I have started to build apps with vuejs recently and have one small issue that I can't get around:
I am using vue-router to jump between pages and lets say I have a huge list where additional items may be injected with ajax, user has to scroll, he click on item, see the details (is in new route) and when gets back list is reinitialized and has to scroll again to be at the point he was previously. Do I have some possibility to keep the state of given component (and view like scroll position) while using vue-router or do I have to keep some cache-instance in main app component and then map it on init?
Thank you.
Essentially, the issue is that your component stores state internally. Navigating away clears the state. There are two ways I see this could be handled.
1) (quickfix) instead of redirecting use another way of displaying the item details (modal, or expand come to mind). This way the state of the component is not lost
2) (the "proper way") store the state. Inevitably, you'll come up against this sooner or later and the best way to deal with storing a state is vuex. https://vuex.vuejs.org/en/intro.html Initially, this will require a bit of learning and add some complexity, but it is a worthwhile investment
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. :)