React Component Not Refreshing When Redux State Has Been Updated With Successful Action

React component not refreshing when redux state has been updated with successful action

I was doing everything correctly just not accessing the state object appropriately. Stared at this one a little too long.

const mapStateToProps = state => ({
gradient: state.getIn([reducerUI, 'gradient']),
chat: state.getIn([chatUI, 'chatSelected']),
auth: state.getIn(['auth'])

});

React/Redux - Component not updating despite Redux state change

In your Location reducer, the state name is gps, so the state name should be mapped in the component. Because the state gps is updated. Please change the state name as to below

const mapStateToProps = state => {
return { coordinates: state.gps };
};

Redux state is not updating after adding a blog post

The problem seems to be that React doesn't know that a new post was created. You'll need to call getPosts() after createPost() has been called.

const submitHandler = (e) => {
e.preventDefault();
dispatch(createPost({ post }));
dispatch(getPosts());
}

If you want to structure your services in a more centralized, scalable way, check out my blog post on React services: https://schneider-lukas.com/blog/react-connect-rest-api. You could just as well store the posts in the Provider component to make them available to all components in the tree, or better yet create a separate Context, Provider, and Consumer for handling posts.

React redux state update isn't reflecting to related components

Thanks for all the comments. It appears to be I'm updating the state in a wrong way.

//redux payload actions
const stateActions = (state = initialState, action) => {
switch (action.type) {
case 'UPDATE_DATES':
// state.dates = [...state.dates,...action.payload];
let dates_arr = [...state.dates];
state.dates = [...dates_arr,...action.payload]
return {...state}
}
return state;
}

Which is working fine and updating all the components.

Component not updating when redux store modified

In React, components update when one of three things happen:

  • Props changed
  • State changed
  • forceUpdate() is called

In your circumstances, you're looking to update ActiveCampaignsDropdown when state.activeCampaigns changes in the store. To do this, you must hook up your component so that it receives this value as a prop (and thus force an update when it changes).

This can be done as follows:

import {connect} from 'react-redux'

class ActiveCampaignsDropdown extends React.Component { ... }
const mapStateToProps = (state) => ({activeCampaigns: state.activeCampaigns});
const Container = connect(mapStateToProps)(ActiveCampaignsDropdown);

export default Container;

The final Container component will do all the work of connecting ActiveCampaignsDropdown with the desired store state through its props.

Redux's connect() also allows us to hook up dispatch functions for modifying data in the store. For instance:

// ... component declaration
// ... mapStateToProps

const mapDispatchToProps = (dispatch) =>
{
return {
getActiveCampaigns: () => dispatch(getActiveCampaigns())
};
}

const Container = connect(mapStateToProps, mapDispatchToProps)(ActiveCampaignsDropdown);

Once the mapping functions are defined, the container component is created, and the container is rendered, ActiveCampaignsDropdown will be hooked up correctly. In my example, it will receive 'activeCampaigns' and 'getActiveCampaigns' as props and update accordingly when their values change.


Edit:

After taking another look at your code, I believe your issue is due to the fact that no condition has been met in order to update ActiveCampaignsDropdown when the website has changed. By calling getActiveCampaigns() from your WebsiteDropdown (as per your comment), this is forcing state.activeCampaigns to change, which successfully updates ActiveCampaignsDropdown. As mentioned in one of my comments, 'forcing' this change from a component whose responsibility isn't to do that would be considered bad practice.

A perfectly reasonable solution is for ActiveCampaignsDropdown to 'listen' for changes to the current website and update itself accordingly. For this, you need to do two things:

(1) Map website state to the component

const mapStateToProps = (state) => {
return {
activeCampaigns: state.activeCampaigns.activeCampaigns, // unsure why structured like this
selectedWebsite: state.selectedWebsite.selectedWebsite
}
}

(2) Move your dispatch call into componentWillReceiveProps

class ActiveCampaignsDropdown extends React.Component
{
// ...

componentWillReceiveProps(nextProps)
{
if (this.props.selectedWebsite !== nextProps.selectedWebsite)
{
this.props.getActiveCampaigns();
}
}
}

Now every time the selected website changes, a refresh will occur and componentWillReceiveProps() will be called (causing activeCampaigns to also update). When this update has been applied, another refresh will happen and the rendered dropdown will contain the newly updated campaigns.

Some minor improvements:

  • If a number of your components rely on the state of the current website (which I imagine is many), then you may consider providing them with it via context.

  • Now that your ActiveCampaignsDropdown receives 'selectedWebsite' as a prop, you can pass this directly to your action function instead of having it fetch it from state (using getState()) - which by the way should also be avoided if at all possible.



Related Topics



Leave a reply



Submit