React global state update local state - reactjs

I need to update the local state after a global state is updated.
I tried mapStateToProps but this only maps the global state into the component, it does not update the local state.
Please refer to image to see the code.
after mapStateToProps is updated, the values on the selected_smsf_member should be parsed into the local state which is used to create the form.
I am also open to suggestions of a better approach. Basically what I am trying to do is to show the details of a selected member on a previous component.

As you can see mapStateToProps, its name says everything, It will map state to props, you can access its variable in your props, like this.props.selected_smsf_member in your component. If you still want to update your local state, using getDerivedStateFromProps(), but read this blog first: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html

You could utilize getDerivedStateFromProps. You can check your props and derive state from it when they change. A few notes though:
You should initialize your state.memberDetailsForm as a falsey value and check that in your getDerivedState function otherwise it'll derive your state EVERY TIME the props change which would lead to unexpected consequences.
I don't know the exact mappings to your code so don't just copy the
example below and expect it to work.
Implementing this method should get you the output that you want.
static getDerivedStateFromProps(props, state) {
if (!state.memberDetailsForm) {
return { memberDetailsForm: props.selected_smsf_member }
}
}

Related

React/Redux updating and accessing state value

How can I update a local state and then access the updated value within the same function scope?
I am trying to update the store in redux,
I am taking values from a local state,
I'm doing this from inside the same functional scope that the state is being updated in.
when I do this, the pre-updated value of the local state is being passed to the store
I have tried adding a useEffect to the code which watches the state to try and make it update the value of the state in the function scope, but it doesn't work.
Because we are having one button do everything at once, it is all wrapped in one function.
I'm sure the solution is using async/await, but I am not so hot with that!
What I understood. State of Component then -> update Redux Store, then read the store. What you should do is: Create an action to update the store, use react-redux to dispatch the action. https://react-redux.js.org/api/connect.
Use mapStateToProps to read the store state and use it in your component.

setState() hook - setting state variable directly?

I was under the impression that a second "setter" method param was needed for setting variables to state with the useState() hook. For example, in the following line of code, "widgets" would be used to get widgets from local state but setWidgets() would be needed to set widgets to state:
const [widgets, setWidgets] = useState(new Map<string, JSX.Element>());
However, I inadvertently wrote code to set widgets directly to state via the widgets state variable:
widgets.set(...)
I confirmed that this approach is successfully setting widgets to local state. Was the second param required in earlier versions of React hooks and the useState() hook has been simplified to support a single parameter as described above? If so then do you know in which version of React this was introduced? Or am I possibly doing something in my code that is only making me think that the 1-param useState is valid?
Maps, Sets and other complex objects can be updated, but you won't trigger rerenders by calling they're native methods, as the object reference itself would be the same. The overall effect of this becomes evident on these type of state values being passed down through props or context.
The proper way of handling setting state on this type of object is something like this:
setWidgets(prev => {
prev.set(id, value);
return new Map(prev);
})
This ensures that the object reference is updated so that changes are properly propagated.
widgets.set(...) is wrong. It might seem to work depending on how it is used, but the state should always be updated immutably using the second element of the array returned by useState (setWidgets).
You can update the map immutably like this:
setWidgets(prevMap => new Map(prevMap.set(key, value)))
BTW storing JSX as part of the state is bad practice.

ReactJS constants that changes dynamically(Dynamic global)

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.

Reducer Props getting changed in the component

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

Setting initial state from Redux

I have stored username, full name & email address in redux store. I have a component that needs the email address so it can make an API call to obtain the users group information (using domain - i.e chase#gmail.com becomes the key for the database query using gmail.com). The component is connected to the store and uses mapStateToProps to obtain state information.
Is it an anti-pattern to do something like this in this.stat = { }
this.state = {
group: '',
owner: this.props.user.id,
domain: this.props.user.email.split('#')[1],
errors: {},
}
Thank you for all the suggestions.
Its not good practice to duplicate redux state in the local state.
Why? Because it is not scalable. Imagine if you r data will be need to change. So you will need to update both your local state and redux state. And also, if your redux state will change - you need to update local state. It will becomes to spaghetti.
What you can do?
You can just use only your data from props. Implement shouldComponentUpdate method to be sure, that your data will be always up-to-date.
shouldComponentUpdate(nextProps, nextState) {
return this.props.user !== nextProps.user
}
And use the data from the props.
I prefer to use them based on my thumb rule.
If you need the data be instance specific - use state.
Example: you have a button group component, keep the data in state since there is a possibility of multiple usage of the component.
If your data is required to be global, so that anyone can modify it from any other component, and specially if you want the data to be tied in to an external source, use Redux state. Since the data is external to your component, it becomes damn simple to manage it.
Link: https://github.com/reactjs/redux/issues/1287

Resources