Redux: Component won't re-render (universal)

Created on 23 Aug 2015  路  23Comments  路  Source: reduxjs/redux

I have an action posting to my database, with the reducer successfully posting the response to my state. This works fine, however my component isn't re-rendering automatically, I can only use the updated component with a manual re-render.

Here's my component:

export default class Colours extends React.Component {

  componentDidMount() {
    this.props.getColours();
  }

  render() {...}

  addItem = () => {
    this.props.postColour({ 
      colour: 'pink' 
    });
  }

}

my action:

import req from 'axios';

export function postColour(value) {
  return {
    type: 'POST_COLOUR',
    promise: req.post('/api/colours', value)
  };
}

and my reducer:

import Immutable from 'immutable';

export default function colourReducer(state = new Immutable.Map(), action) {
  switch(action.type) {

    case 'POST_COLOUR': {
      return state.merge(action.res.data.colours)
    }

    ...
  }
}

Am I missing/doing something completely wrong for my props not to be updated as soon as the response is merged with my initial state?

Thanks!

question

Most helpful comment

I honestly have no idea, i'm on OSX too.

You're right I didn't even notice that, that shouldn't work at all..

I've just updated my io.js to 3.1.0 and now I'm getting your error haha.. would you be able to leave this open and i'll let you know when i've fixed it?

All 23 comments

React Redux version?
How do you connect Colours to read the Redux state?

Using 1.0.0-rc.

Here's the parent component where I connect:

@connect(state => ({ 
  colours: state.colours.get('colours'),
  typography: state.typography.get('typography')
}))

export default class App extends React.Component {

  render() {

    const { colours, typography, children, dispatch } = this.props;

    const bindDispatch  = { ...bindActionCreators(actions, dispatch) };
    const mergedProps   = assign({}, { colours, typography }, bindDispatch);

    return (
      <div>
        <Header />
          { React.cloneElement(children, mergedProps) } 
      </div>
    );

  }

}

What version of react-redux are you using?

Sorry my bad, 0.8,2

Any chance you could share the project to reproduce?

Just added you as a collab

Thanks. I can't get to start it. I installed nodemon, it crashes with serve-favicon missing, I installed it, now it crashes with body-parser missing, etc. Can you please declare all dependencies?

Just updated repo!

Dependencies work now, but now I get this:

    throw err;
    ^
Error: Cannot find module 'server/routes'
    at Function.Module._resolveFilename (module.js:332:15)

pushed again, very strange it's working on my machine, trying to think if I have anything globally installed that would make a difference..

Still not working.

 62% 228/259 build modulesmodule.js:334
    throw err;
    ^
Error: Cannot find module 'server/routes/routes'

I'm on OSX if that matters..

By the way I'm curious why non-relative routes are supposed to work. Shouldn't it be ./server instead of server?

Also, I'm using io.js 2.2.1

I honestly have no idea, i'm on OSX too.

You're right I didn't even notice that, that shouldn't work at all..

I've just updated my io.js to 3.1.0 and now I'm getting your error haha.. would you be able to leave this open and i'll let you know when i've fixed it?

Yeah sure.

Ok fingers crossed this one works.. Thanks for bearing with me !

It's working! What should I do to repro?

Ahh good,

If you go to /colours, and press the '+' on the page it posts a colour to mongo, however the component doesn't re-render. If you refresh/componentDidUpdate then the state updates

So, I added redux-logger and here's what I see:

screen shot 2015-08-24 at 02 23 36

Oh wait, I see your point, this is exactly what you wanted state shape to be..

Here's the action I see. There's no action.res.data.colours in it.

screen shot 2015-08-24 at 02 33 24

It's also a bit strange that you seem to be using Immutable structures for states, but state.set('colours', action.res.data) will just put action.res.data (a plain array) into the state. The React components also seem to be expecting plain arrays and objects. Why use Immutable on just one level?

I sent a PR. The problem was that the data that the reducer tried to use wasn't present in the action object, and also that mutable objects weren't converted before being put into Immutable maps.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mordrax picture mordrax  路  51Comments

erikras picture erikras  路  63Comments

ronag picture ronag  路  46Comments

wmertens picture wmertens  路  55Comments

gaearon picture gaearon  路  69Comments