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 !
Related
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.
I'm working on a React + Redux project with a couple of other developers and we can't agree on what the best practice is regarding where to pass in the state and the actions.
My approach is to have a 'container' or 'provider' component, which is the parent component, all required states and actions are mapped to state and passed down into child components, creating a single source of truth. However the down side to that is, you have to remember to pass actions and values down through each child component, which can be tricky to follow.
Another developers approach is to use the mapStateToProps on each component where it is needed, at any point in the stack. So if a child component three or four levels down requires a certain state, he would use mapStateToProps on that component. He would also import action creators directly using the import keyword, instead of calling them as props. I don't like this approach because you're potentially injecting states multiple times and you can't switch out your state or actions quickly in one place.
I can see both approaches have their merits and fallbacks, so I just wondered if there was a definite best practice as to where and when to inject state/actions into a stack of React components.
I worked on a relatively large Redux codebase and the approach we chose and which I like was your second approach using mapStateToProps on containers component which dispatch actions and delegate rendering to dumb components.
You want to be able to reuse them in many places without having to pass down a state. Your top redux state is still the source of truth but mapStateToProps will allow you to access only the part of the state which you need within this container.
Redux documentation is amazingly well done, check it out, it recommends container components implementing mapStateToProps http://redux.js.org/docs/basics/UsageWithReact.html
It's up to you how many components you connect to Redux, but generally speaking having more connected components is better for performance. For more information, see the Redux FAQ on connecting multiple components, as well as my blog post Practical Redux, Part 6: Connected Lists, Forms, and Performance.
I'm about to start a new React project and am trying to draw on my previous learnings to create some rules about how I structure the app.
Some things I believe to be true:
Redux holds the 'main' data for the whole application
Redux can hold UI state if it needs to be shared across the application (e.g. global modal windows that can be launched from anywhere)
Components can hold their own state with setState if that state doesn't need to be shared anywhere else in the app.
Stateless components should be used wherever possible
When I am creating a component that needs state from Redux, I will create FooContainer.js and FooComponent.js files - the Redux connect code will sit in the container.
There are large parts of the app that are UI heavy and have a lot of UI logic/state going on, but do not need any state from Redux.
I feel that with the liberal use of component-level state, I should be using more Container Components to compose smaller, stateless components. However, I see a lot of definitions of Container Components as "a HOC that connects to Redux"
Does it make sense to have a project that has many container components, where some are Redux connected and pass data from the store to their corresponding presentational component, and others that are not Redux connected but are just used to compose smaller components and manage local state?
If so, are there any recommended file structures, naming conventions etc to distinguish between the two?
A few thoughts.
First, it's important to understand that a "container component" is simply any component whose primary job is to fetch data from somewhere and pass that data to its children. This could mean making AJAX calls to retrieve data, or accessing Flux stores. That means that the wrapper components generated by React-Redux's connect function are "container components", because their only job is to extract data from the Redux store. It also means that components whose job is to manage UI state are also "container components". See Dan Abramov's original article on container and presentational components.
Second, it's entirely fun to use class components and functional components, as much or as little as you want. That's purely up to you.
Third, while you can define your "plain" components in one file, and "connect" them in another file, I personally tend to see that as unnecessary separation. Most of the time, a given React component will only be connected once, so it's perfectly reasonable to define the component and connect it in the same file.
You may want to read through some of the articles on Redux Architecture and Project Structure in my React/Redux links list for more information.
Revising your assumptions:
Redux holds the 'entire data for the whole application in a store.
Redux can hold UI state if it needs to be shared across the application in the store.
Components do not hold their own state they reference the main store (even indirectly using connect)
Stateless components should be used wherever possible. State is passed by the container.
When creating a component that needs state from Redux, I will create FooContainer.js and FooComponent.js files - the Redux connect code will sit in the container.
Answering your questions:
Does it make sense to have a project that has many container
components, where some are Redux connected and pass data from the
store to their corresponding presentational component
Yes - Dividing your app in smaller components with their own containers is good practice.
and others that are not Redux connected but are just used to compose
smaller components and manage local state?
Not really IMO - In Redux the state of your app should be kept only in a unique store. Still you can have smaller simple components in a container if related.
I'm looking at ReactJS as being the view in my application which has a model and a bunch of components. I can see how my model can talk to React, but how does React then talk to the rest of my application?
It's very simple to pass in data or a model into React:
var ui = ReactDOM.render(<UI model={model} />, document.getElementById('ui'));
I assumed you could set the model like so:
constructor(props) {
super(props);
this.state = {
model: this.props.model
}
}
Although state should treated as immutable according to the documents, as it's not updated instantly. So I cannot access my model through state, I have a very bad codepen example here showing how I've made it work in the wrong way. How else can I do this?
There are literally hundreds of ways to connect your React view layer with an underlying model. React itself is completely implementation agnostic when it comes to models.
However, there are some interesting approaches to this problem that have proven themselves.
One of them is Facebook's Flux pattern. It is based on the idea of data stores that are kept separately from the React components without a direct dependency on them. Instead, changes to your model data are made by dispatching actions (e.g. user logged on, filter was applied), which can be thought of like events. Those actions are then dispatched by a central dispatcher to the different stores.
Each of the stores holds a different part of the state of your application and continuously updates it according to the dispatched actions. Your React components can now pick and choose the parts of the state that they require to be rendered and subscribe to changes to this particular part of the application state.
(source: github.io)
By applying this pattern, you can keep the dependencies between the React components, which render your user interface as a function of the application's state and the stores, which represent your application's model and contain all the business logic.
This ensures both that the parts of your application stay reusable and replaceable and also that the state of your application is always consistent.
Note however that, as mentioned above, this is only one possible approach amongst many. It may be a good entry point though to understand the value behind the unidirectional dataflow and immutable data structures that make this pattern so powerful.
Having spent some time working with flux (both ‘vanilla' and with various frameworks including alt and fluxible) I am left with a question about best practice with regard to loading the initial state of components. More specifically about components directly accessing the store to do it.
The flux ‘model’ prescribes a unidirectional flow of data from Action>Dispatcher>Store>View in a loop, yet it seems this convention is eschewed when loading the initial state of components, most docs/tutorials contain examples where rather than firing an action to get the data, the component calls a function on the store directly (examples below).
It seems to me that components should have little/no information about the store, only about the actions that they can fire, so introducing this link seems both unintuitive and potentially dangerous as it may encourage future developers to jump straight to the store from the component instead of going via the dispatcher. It also runs counter to the ‘Law of Demeter’ which Flux is supposed to adhere very strongly to.
What is best practice for this? Is there a reason that this always seems to be the case? Its quite possible that I have missed out something fundamental, so please let me know if so!
Thanks.
Examples of components calling the store directly.
Flux React example from the fb flux repo example chat app (https://github.com/facebook/flux/tree/master/examples/flux-chat)
MessageSection.react.js
getInitialState: function() {
return getStateFromStores();
},
function getStateFromStores() {
return {
messages: MessageStore.getAllForCurrentThread(),
thread: ThreadStore.getCurrent()
};
}
Another example from the same repo for the TODOapp
(https://github.com/facebook/flux/tree/master/examples/flux-todomvc)
TodoApp.react.js
function getTodoState() {
return {
allTodos: TodoStore.getAll(),
areAllComplete: TodoStore.areAllComplete()
};
}
Example of the alt implementation of the above todo app: (https://github.com/goatslacker/alt/tree/master/examples/todomvc)
TodoApp.js
function getTodoState() {
return {
allTodos: TodoStore.getState().todos,
areAllComplete: TodoStore.areAllComplete()
};
}
and finally the alt specific tutorial:
(https://github.com/goatslacker/alt-tutorial/blob/master/src/components/Locations.jsx)
Locations.js
componentDidMount() {
LocationStore.fetchLocations();
},
It depends on how the structure of you app looks like. Often you want to fetch some data before showing something to the user. What I have found to be a good practice is to have a high end component which fires on mount an action which fetches any initial data from an API. This means that when this action is done fetching it calls the store which caches the data and then emits a change.
This change emit then sets in motion the re-rendering of the whole application.
This way you keep the uni-directional data flow. The whole point with Flux is letting the user extract the data flow functionality out of components to keep them more clean, discourage components to directly communicate with each other and decrease the amount of unnecessary properties which has to be passed around the application.
In the examples the initial state fetches some initial value from the store. This is a common way to fetch the initial value, but you could set it in the component as well. Both ways I would say is a good practice. This does not mean that every component is free to fetch whatever they like from the store.
Anyway, the goal would be to keep the code and data flow as intuitive as possible with Flux. All of this are reasons why there are so many implementations of Flux.