I am very confused recently.
When I write redux, if I have to call api ,I will put an action to update reducer, the component just render the data from props
But recently I see my coworker just call api in container component and then update the component state.
He says if your data do not need to share with other component, you can call api in component, so you don't have to write so many code in actions and reducers.
I thought this is very convenient. For example: If I have a feature : When user click the button, I have to send an email.
This feature do not need to update store by reducer, just have to alert "send success"
So I can write this code in container component:
async onClick() {
// 1. call api
const {error, response} = await sendMail({email: this.state.email});
if (response){
// 2. alert success
this.setState({
modal: {
show: true,
}
});
}
}
But I don't know if this match redux's principle.
Can I call api directly in component if the state do not need to share with other component??
You can call api from dispatched actions or from React components: it is your choice to make. There is no mandatory rules here and it depends on what you want to do with your components:
When to use React states:
It is better to have smart component handling their own state because it ease the integration in external projects. Having a component that uses Redux means a project needs to add the requires reducers to use the component.
If a component handles information not required by any other components, use React state. It is often the case for information related to UI state.
When using Redux reduces:
If you need to test your component, prefer Redux because you'll be able to connect "test actions" to your component when testing them.
If you need to share a bundle of data through components, prefer Redux to mutualise information.
This question has been treated by Gaeron on Redux github repository if you want to have a look. He explains:
Use React for ephemeral state that doesn't matter to the app globally and doesn't mutate in complex ways. For example, a toggle in some UI element, a form input state. Use Redux for state that matters globally or is mutated in complex ways. For example, cached users, or a post draft. Sometimes you'll want to move from Redux state to React state (when storing something in Redux gets awkward) or the other way around (when more components need to have access to some state that used to be local). The rule of thumb is: do whatever is less awkward.
I suggest you have a look at classux
Related
I am just going through a confusion so far. I am developing a React application for that some amount of API call is required. so I just confused with whether calling the API in the component and passing the dats by props to the required components or Using redux thunk to fetch the api's and store in to a React store and fetching the required data by dispatching the action when ever it required.
Suggestions will be appreciable :)
Calling the API is surely gonna be done in the component. Like so:
const Component = () => {
useEffect(() => {
const fn = async () => {
await apiCall()
}
fn()
}, [])
}
But your question resides on where you should store it.
This is simple:
If the data you are getting are gonna be used across the whole app, then Redux is a great option. It also comes with data persistence with very little effort using redux-persist (https://github.com/rt2zz/redux-persist) so it's not only to have a global object you can access.
Features:
a. Persistance
b. Global state accesible anywere
c. Enhanced debugging with Redux dev tools
If you only want to avoid prop drilling then React.Context is a good option
If you are only drilling 2 or 3 leves with your props, just don't overkill it using a Context
I strongly recommend not to use React-Redux. Here are the reasons
Why should you add a library in your application just for passing states
Redux comes with code of overhead(writing actions, etc)
React's Context API can solve your problem (which is already available in react library)
React Composition is another way of passing states to child components.
Redux has maintenance overhead as well.
All in all, your React can manage all your state communication problems alone. You don't need another library for state management.
Note: Whenever I say React, I mean React newer versions. React 16.8+
**Is it OK to Using a component state for just to handling form data, while the main data and other stuff of the application will be stored in the Redux store?
I don't want to use redux-form instead manually dispatch it to the reducers**
Redux comes into the picture when we want to manage the state across different component. It provides a centralize store where state of all the components are managed.
When talking about forms, in most cases form data is only limited to the component is which is being used. So, in that type of scenario there is no need to link them to centralized store using redux. A simple way is to store them in the component state and get it processed. Afterwards, you can store the output of that in redux store according to your needs.
It is okay to do that. You can keep a local state in the component. state = {} in class components, const [localState, setLocalState] = useState() for functional components.
Or you can use custom hooks for handling your local state needs. Check out useInput or useForm custom hooks that are developed by the community.
Yes of course. Some things go best in component state, some go best in a parent component, some go in Context, and some go in Redux. There is little use in putting everything in Redux, it just causes a lot of boilerplate and every component tries to update when the store changes.
You put things in Redux when different components that are at different places in the HTML tree use the same data, and it changes during the app's lifetime (things like the user's language don't change often and go in Context). You use it when you want to store your app's state to restore it later (which exact menus are currently open or closed is usually not that important) and when you want to keep track of state changing using the Redux dev tools.
I'm new to React and I'm trying to figure out the best way to request information from the server based on the URL. I'm using Redux and React Router v4.
Let's say I have a route /foo/:id, and a component Foo that will render something based on id. However Foo needs some server data related to id to do so. I believe the way to accomplish this would be to use mapDispatchToProps to create a function that takes id as input, does some async work, dispatches an action, and ultimately updates the redux state.
My question is: where is the most appropriate place to invoke the dispatch? In this scenario, there's no form submission or button click to kick things off. Originally I was thinking of including a check for the id data in render() and fetching if it was not populated, but this felt wrong due to the side effects.
You can do it in componentDidMount of the Foo component, similar to this example from the Redux GitHub project.
Your intuition is right that render is not a good place to do so. Most people do it in the componentDidMount lifecycle method of the component.
On a relevant note, you will also want to do fetching also in the componentWillReceiveProps method like what they did here. Reason being if your user navigated from foo/1/ to foo/2/, the component is already on the screen and will not be mounted again, hence componentDidMount will not be called again. The fetching for the second user will be done in the componentWillReceiveProps method.
i think the best way to do the dispatch inside the componentWillReceiveProps() which would help you fetch some data before the component renders
It seems your use case is well-captured by the react-refetch package which you can find here. It provides a higher-order component that allows you to specify dependencies at specific API endpoints and then resolves them when a new instance of your component is created.
Importantly it injects the data into your components props using a synchronous abstraction of a promise called a PromiseState. This will allow you to conditionally render your component depending on whether the data is say pending, fulfilled, rejected, etc.
This is not attached in any way to Redux, it skips that layer entirely, so do keep it in mind that the response is directly injected into the component and does not go through your redux store's state.
I've been learning Redux and a part I'm unclear of is, how do I make a determination between using react state vs redux store and then dispatching actions. from my reading so far it looks like I could use React state in place of Redux store and still get things done. I understand the separation of concerns with using Redux store and just having 1 container component and the rest of it as stateless component but how do I make the determination of when to use React state Vs redux store is not very clear to me. Can someone please help?
Thanks!
If the state doesn't need to be shared with other components, or the state doesn't need to be keep when the component is unmounted, then you can just put it in the component's state.
You can think that the Redux store is the database of front-end, if you have something like product data fetched from an API, then the Redux store is the right place; if you have a dropdown component, which takes a isOpen prop, then the parent of that dropdown can just keep dropdownIsOpen as a component state.
For more information, here is the answer from Dan: https://github.com/reactjs/redux/issues/1287
Also you said
only 1 container component and the rest of it as stateless component
This is incorrect. You can have several container components. A container component can also contain another container component.
From book:
First of all, we should always keep in mind that only the minimal
amount of data needed should be put into the state. For example, if we
have to change a label when a button is clicked we should not store
the text of the label, but we should only save a Boolean flag that
tells us if the button has been clicked or not. Secondly, we should
add to the state only the values that we want to update when an event
happens, and for which we want to make the component re-render.
Another way to figure out whether the state is the right place to
store information is to check if the data we are persisting is needed
outside the component itself or by its children. If multiple
components need to keep track of the same information, we should
consider using a state manager like Redux at the application level.
There are a few things that need to be grasp
State of component: If you want to keep state-specific to your HOC then use state. Now in the function component, we use useState.
State of redux: If you want to share data throughout the application use redux state.
Store of redux: It's nothing but a database for the redux library. In the case of redux, we can have only one store. To use multiple stores we can use Flux but it will make things more complicated.
You're absolutely right. Redux (and flux architecture in general) are only formalism tools to help for building large apps. They're not necessary at all.
There's actually an interesting post called You might not need redux by Dan Abramov, the creator of redux that might give you a better answer than I do: https://medium.com/#dan_abramov/you-might-not-need-redux-be46360cf367#.7093fm1z8
If state is needed only for that particular component then prefer to use react state.
For example using state for UI actions
If any state you want to use across the component/project then go with redux state.
For example API response data etc
For detail understanding refer this link
https://spin.atomicobject.com/2017/06/07/react-state-vs-redux-state/
I have a react native project and I am using redux actions and reducers to handle my store.
I have a smart connected component and I call my actions through dispatch in componentWillMount() and then I have mapStateToProps and I map the data I get from my store to props.
Problem is the only way to check if the props are changed, is by putting it inside render function. In my case I want to navigate to another page if I get props filled with some data. It all works fine but I get warning from React that its anti pattern. Is there any other way of doing this? Am I doing it right?
You should implement the method componentWillReceiveProps instead of comparing the values in the render
Another (preferable) approach would be the action responsible to update the values, do the navigation (or dispatch another actions that would do the navigation stuff). Check redux-thunk