I am trying to build a new react app and I have some question about the architecture.
I have 2 components:
Adress
CreditCard
Each Component has several inputs and api functions to get the data and also to update it.
When I use both components in one Page, how can I trigger an update for both components?
Page
Address
CreditCard
Submit Button
The Submit Button should trigger the Update function and wait until both are finished.
I tried to give a function from the Page to the child components via props, but I think this is the wrong way.
Redux
For complex interactions between different components you can use redux. Redux holds the state of your entire application and can only be updated with actions.
An action will trigger a reducer. A reducer returns a new version of the state with what ever update you set there.
Treat redux some what like a database, do not store things multiple times and keep a good separation of concerns. There's an awesome library that lets you aggregate and manipulate data called reselect.
Reselect
This library will let you take several parts of the store and combine them for your needs in any given scenario.
Conclusion
To conclude, these's libraries are part of a stack I've been using for about 2.5 years (reselect only 1 year). I've found them very powerful for handling complex data. That being said there are other options like graphql, apollo or relay.
Related
I'm working on a react web app and our company bought an admin dashboard panel to save time. In this panel, they used redux to handle states and all setting parameters stored into redux ...
But really I'm confused about using Redux for each use case!
All of my requests and states are components base and are not global and those are not essential to use in other components of this app!
For example to load games list I've this code :
componentDidMount() {
this.setState({
loading: true
});
http._GET('/game/getAllGames')
.then(response => {
this.setState({
loading: false
});
this.props.dispatch(gamesListAction(response.data.result.games));
});
}
In this case, I use a response and list only on the games-list page. So I think it's not logical I store a response.data into redux and then get all data with connecting and another process...
Or another example, for inserting forms I'll never need to store forms insert or API response because it's inserted and not getting data from API!
I've read about redux but I think redux is not suitable for every app and use case and I should not store single-use responses to redux.
The reduxjs FAQ describes it the best.
In general, use Redux when you have reasonable amounts of data changing over time, you need a single source of truth, and you find that approaches like keeping everything in a top-level React component's state are no longer sufficient.
Redux is nothing but a state mangement tool and you need more compelling reasons to use it:
In your case, firstly:
React's setState will bloat the component overtime with growing requirements and it is much
harder to maintain. Separating out the state management into a reducer
refactors nicely and makes it more readable.
Caching component state, for example if you are using a shopping cart, progressive wizards. There a is lot of to and fro in user interaction which result in state changes, in such cases. Maintaining your state in redux makes a lot of sense now.
Deeply nested components passing on state and lots of props to their children quickly bloat with growing requirements. This is a classic scenario with lot of wrapper components (especially with UI details). A better way would be to refactor and directly connect low level components to redux (transform into a container. Read: presentational-and-container-components)
Application state mapping to multiple container components. For example, if you had your getAllGames loading state to be represented in some progressive-loader-component somewhere out in your app. Using redux will ease your pain sharing data between this components.
Useful when building root level components which can possibly have interactions from everywhere. Like your useraccount component, modal, alerts, loaders.
You will realize, you are writing some boilerplate code with actions and reducers. Though overtime this is much better than reacts state management which can progressively grow complex within stateful components quickly.
Yes, You are right redux is not suitable for every application, as per my knowledge redux or state management is used mainly if you want to show the user previous state instead of empty when some operation is happening
Here is a bit detailed explanation about when to use redux
https://medium.com/#fastphrase/when-to-use-redux-f0aa70b5b1e2
Happy Coding !
Say I want to create a little editor for my software that helps me organise people in my company. I will use React & Redux. The editor is a React component (or maybe container?), and it shows me one person at a time. I can edit things about this person, delete fields, etc. and when I am ready I can click a button which will then give me the next person to edit.
Now, I am quite new to React still and can imagine doing this in 2 ways:
Solution 1: Decouple the editor component
Create an Editor Component, which takes an array of all the people in my company. I do have these people saved in the Redux state of my app, but the editor component will not work on my Redux state, but do all changes in its internal state first, and only once I click save will the Editor component commit these changes to my Redux state. This might be a problem, and changes could get lost if somebody doesn't save their edits.
The advantage here is that I have my Editor de-coupled from the rest of my App, and the logic of the Editor will stay in that component.
Solution 2: Connect the Editor Component to Redux
Here, I would connect my Editor component to Redux. So I would not give my component the people array, but direct access to the my Redux store via selectors (for example). I would also not have a deletePerson() function internal to my component, but pass this down as a prop into my component (and it would presumably be a Redux action). This way my component would work directly on state, which I can see as having advantages.
But taking it out of this app and reusing it somewhere else would get more and more difficult, the more complex my component becomes.
Please remember that I am a beginner and that these two solutions are what I came up with as a response to a problem I am facing in my own application. However, I would appreciate if you could help me out here, and explain to me how I should think about problems like this. Is there maybe a third solution I am not mentioning? Or am I misunderstanding a concept?
Personally, I am inclined to go with Solution No. 1, but I also know that the whole idea of Redux is to keep state in one place. What would you advise? Are there performance differences / advantages with one solution?
Your first solution is good but why not use a service when its provided?
You should try to mix up features of Redux React. First, separate your presentational and container components and in one of your container component pass the props directly to redux store on click,etc. Then use redux actions to access the store like deleting,etc. Provide a UI using React presentational components for data entry and pass this data to redux store. Use redux actions when you think they will be useful and not destructure your app.
Go to https://medium.com/#dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0 for further details on how to connect presentational and container components.
If I use react with redux - does it always necessary to fetch data from the redux action? Or it depends if I need the data to be stateful?
For example: I have a container which displays a user profile page. Can I fetch its data from the componentDidMount?
Thanks.
Below a list of rules of thumb which could help you to determinate what kind of data should be put into Redux or in your component, I tried to write down few assumptions, but please in mind you know only the right answers :):
Is the data used by other part of your application? Probably in your case yes as a User Profile property like name could be used in different components, like the head of your site, profile details, basket.
Do you need to be able to create further derived data based on this original data?
Is the same data being used by multiple components? Probably yes.
Do you need to cache the data? Probably no.
Yes - this is how you would fetch it if there wasn't redux being used.
If you want to use redux (to make profiles available in general etc.), you should call the action from componentDidMount to properly handle lifecycle events etc.
In my application, there are views with dependencies. For example, in one view a user could select an item from a list (generated on the server), and in next view the user would perform operations on the item. The item is passed to the second view in props. I'm moving to using react router, but there are some difficulties:
I can't use props for transferring data anymore. What would be a preferred way to pass data? Do I have to use redux?
Users can navigate from any view to any other view by directly using url. However, some transitions don't make sense: e.g. user navigates to item editing view from somewhere else, and therefore does not have an item selected. Is there a way to limit allowed transitions?
This is a very broad question, but I'll take a stab at it.
Can you use Redux? Sure, Redux is good for centralizing your state which can easily be shared among your components. As far as limiting the url's they have access to, I would use your reducer to look at your current state, if you're using Redux and if data is not there, meaning they should not be at this step, use a javascript redirect to where they should be instead.
Finally, you don't have to use Redux to share data between components this could be done by setting global variables your components can access, but cross component communication is where Redux shines.
I am a bit lost on what to keep in the state tree of Redux.
I saw two conflicting statements on what to store in the state tree(s).
React doc tell us that only user input should be stored in state trees.
The original list of products is passed in as props, so that's not state. The search text and the checkbox seem to be state since they change over time and can't be computed from anything. And finally, the filtered list of products isn't state because it can be computed by combining the original list of products with the search text and value of the checkbox.
Redux doc tells us that we often should store UI state and data in the single state tree:
For our todo app, we want to store two different things:
The currently selected visibility filter;
The actual list of todos.
You’ll often find that you need to store some data, as well as some UI state**, in the state tree. This is fine, but try to keep the data separate from the UI state.
So React tells that we should not store data (I am talking about data of the todos) and, for me, Redux tells the opposite.
In my understand I would tend on the React side because both React and Redux aims to predict a UI state by storing:
all what can't be computed (eg: all human inputs) and are part of the UI:
checkbox value
input value
radio value
...
All minimal data that could be use to build a query and send it to the API/database that will return the complete user profil, friends lists, whatever...:
user Id
creation dates range
items Ids
...
For me that excludes all database/API results because:
that stands on data level
could be computed by sending the right (and computed by pure reducers) query.
So what is your opinion here?
React documentation about the View Component state, but Redux documentation about the Application state. So, there is no conflicts between definitions.
If we talk about Redux - you make all your components without state (and transform stateless root component to stateful with help of react-redux's connect function). If you have large response from the server and you show your data with pagination / filters, you can treat your application state as what you see on screen and not put all data in Redux store, only what you need to render (for example, 100 rows to show page and total number of rows to show pagination). There is no restriction for this. The whole data you can put into another place. For example, in another data container in web-worker (I make a full request in web-worker and fetch from there only needed data to display).
Added after question edited:
The original list of products is passed in as props, so that's not state.
In that example, the reason why list of products isn't state - it's already in props. It means that the one of parent components have this as state.
I feel that the problem is that originally Redux was pushed really hard, and some people were so purists, that they argued for separating everything to Redux and re-rendering the whole application on every change. And then we ended up with this response of the creator, which actually only added a confusion, because redux was and still is a de-facto standard for new react applications, and a lot of tutorials assume it.
So, I feel that people are pressured from each side, and often they do some things without real understanding why they should (especially newcomers creating constants, actions and reducers). So, for those who read it, please start without redux, and keep it just in local state (but try to keep in some component like DataContainer).
For those who need redux, rule thumb is to put all async data (so all requests go through redux), and data which is needed for independent components. If components obviously located nearby, keep it in a local state and pass as props.
Redux is a very helpful library, but it's power is needed only after you start to have at least several routes, different query options and some complex UI. Before that there is a good chance that you are overengineering (but, of course, if you are sure that you will exceed this size, feel free to start with Redux). And again, you'll literally never will want to put your slider or small dropdown position in the store -- react's state serves perfectly for it.