What would be the best way, while following React best practices, to define globals that changes according to props provided by a redux state.
For example, let's say I have a metric or imperial toggle value that's dispatched into a persisted redux state. Is it possible to call for a constant that changes its value based on the toggle without providing the current state of the toggle by passing it via props?
My current implementation is doing
globals.distance(this.props.metric)
where this.props.metric is mapped from the redux state to the component's props. I want to somehow implement subscription to the redux state from within the globals file, so I can just do constants.distance. I've tried importing getState() as well as subscribing to changes in the redux state, but the problems there is that getState() only runs once when the file gets loaded, and I can't seem export constants subscribed to the state since the function returns an unsubscribe function. I can also create a Component and subscribe that to the redux state, but I can't seem to find an easy way to export constants from within a Component state either.
Well, I couldn't find a solution I liked, so I made my own. It's a thin wrapper to connect functions to the Redux store and return a value.
Related
I have a react project configured with redux for state management.
For api calls I use a file called axiosInstance. In this file I need to have access to redux store (and I have access importing store and using getState - store.getState()). Now the problem is that I want also to update the redux state from this file (axiosInstance).
How I can update redux store from this file (which is not a react component) in a efficient method?
Okay, I assume that you are using Axios for the network calls.
tl;dr
Use store.dispatch(action) and action to make changes to store state
Yes, the store can be accessed with store.getState(), you can also change state with store.dispatch(action). as per the docs
Dispatches an action. This is the only way to trigger a state change.
The store's reducing function will be called with the current getState() result and the given action synchronously. Its return value will be considered the next state. It will be returned from getState() from now on, and the change listeners will immediately be notified.
This happens because of the functional paradigm that redux follows (google for more).
Now, the action has to be defined with an actionCreator, or simply you could call .dispatch() with an inline object with one string property as {type: 'name-of-action'}. This prompts the store to change the state.
You may require redux-thunk for async actions.
Conclusion:
Let's save some trouble here as you may have many calls to the store, you can create a context that handles the AxiosInstance (as there is already a different file for that).
Make a context in the AxiosInstance file and then you can start dispatching actions as per the network responses. this will save you a lot of trouble as the state is updated by redux without actually looking at it much.
In my React app, I have a redux reducer which sends a List as props to my component.
I copy the prop to local state, and show as drop down. User changes the Dropdown so my local state changes.
On click of cancel , I am calling redux Toastr which triggers a method to reset my state with the original props.list. But for some reason the props.list also changed similar to my state change. With my knowledge i thought props passed to the componeent will not be changed until again i call action creator.
Anyone faced similar issue? or i am doing something wrong
Sorry for not posting the code, which I will prepare a demo if needed. Thanks!
What you are doing is an anti-pattern as you are breaking react's rule of single source of truth. You can't hold state internally in a component that is tied up with your redux state and expect it work smoothly. A similar issue of breaking the single source of truth arise when using solely React without Redux and when you try to pass props as state. In this case there is a new lifecycle hook static getDerivedStateFromProps but even this hook is advised to be used sparsely you can read about it here. So if your intent is to reset state back to it's original value, you can either:
Use static getDerivedStateFromProps (which is reserved mostly for UI)
Use a key prop which will reset you back to your initial state
Use a memoization helper such as memoize-one
I understand that mapstatetoprops is mapping our Redux application state to our React component props, but i don't quite understand what's happening behind the scenes when a reducer returns a new state - how does that trigger a re-rendering of components that have props mapped to the application level state?
In pure React, setState triggers a re-render correct? Is something similar (or the same thing) happening via Redux?
Both Redux and React-Redux employ shallow equality checking.
In particular:
Redux's combineReducers utility shallowly checks for reference changes caused by the reducers that it calls.
React-Redux's connect method generates components that shallowly check reference changes to the root state, and the return values from the mapStateToProps function to see if the wrapped components actually need to re-render. Such shallow checking requires immutability to function correctly.
Well the whole point when you create a component using the redux "connect" function, is that behind the scenes you get connected to the redux state, and have a listener for the state changes.
So you create a simple component that gets his values from props, but those props are got from the state using the connect with "mapStateToProps".
Never dived in to the redux-react connect function, but if you want you can surely go ahead and see what it does exactly.
But the main point is what I explained above.
I've converted most of my containers to functional components to make them reusable and I'm wondering if it's good practice to pass Action Creators as props to theses functional components.
In this case, I'm using a tab to switch between Login and Sign Up page and I'm using local state to manage active class (for styling). I call action creators passed down as props to switch between rendering a login or sign up page. I'm using this tab in several places and I'm passing a different configuration object as per use cases.
homePageTabProps = {
firstTabTitle:"blog",
secondTabTitle:"resume",
showFirstTab: this.props.showBlogTab,
showSecondTab: this.props.showResumeTab
}
Is this good practice? yay or nay?
Edit:
The active tab style is giving me problems (retains value when reusing the component). Can I have local & global state? (Sorry if this sounds stupid.)
Passing functions as a props down the hierarchy of your Components is for sure widely accepted practice. But I would suggest not to pass bare action creators, but bind them to dispatch before passing them to Component. This way, if your child Component is not connected to store it will not have to know about Redux at all (no need to manually dispatch).
As for your complication with two states. There is nothing wrong in mixing own Component's state with part of Redux passed to Component via connect. I would even strongly recommend to keep all temporary data not important to your application logic inside Component's state without exposing it to Redux. For example, most of the time, there is no sense in sending animation timings, intermediate state of user input, etc. to Redux.
But, in your case looks like indication of active tab is a direct reflection of Redux state and should be fetched from store. Otherwise it's not clear why you are sending actions to Redux on tab's change.
So in plain react, setState triggers the render method. Now, about Redux, let's say I fire an action, the state returned from the reducer(s) is totally new, so it sounds like every component should get updated, though I know it's not true because when I debug my app I can see it, plus it sounds like awful performance. So my question is, does redux look in each component what state slice it needs? in mapStateToProps? and generally how does Redux decide when to call the render method?
I know Redux has optimizations in it... thanks...
A Redux store offers a subscribe() method. When you use connect(), it generates wrapper components that automatically subscribe to the store when they are created. Each individual connected component is a separate subscriber.
When an action is dispatched, the store runs all the subscription callbacks. The wrapper components then call store.getState(). As a first check, if the root state object is === identical to the previous one, the component will stop there. (This is one reason why direct mutation of state in a reducer is bad.)
The next step is to call the provided mapState function and pass in the current state object. The wrapper component then compares the contents of the object returned from mapState against the contents of the object returned last time, using a shallow equality comparison check. If any of the contents have changed based on that shallow check, then the component knows it needs to re-render the "real" component with the new data. (Again, the "shallow" check is another reason why mutation is bad.)