Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not working component update on state change. #57

Closed
jsifalda opened this issue Jun 7, 2015 · 6 comments
Closed

Not working component update on state change. #57

jsifalda opened this issue Jun 7, 2015 · 6 comments

Comments

@jsifalda
Copy link

jsifalda commented Jun 7, 2015

Few things:
First one: Why this? https://github.com/gaearon/redux/blob/master/src/components/Connector.js#L19 - not sure whether "flux" lib should cream about this part.
Second one: due to custom method shouldComponentUpdate "rerendering" of component does not work.

Look at my code:
Inside container component:

<Connector select={select}>
              {({ userFooter, dispatcher }) =>

                <UserFooter userFooter={userFooter} {...bindActions(UserActions, dispatcher)} />
              }
            </Connector>

select method:

let select = (state) => {
  return {
    userFooter: state.userFooter
  }
}

Store:

const initialState = {
  isAuthenticated: false,
  email: ''
}

let setAuthenticated = (state) => {

  state.isAuthenticated = false
  state.email = ''

  return state
}

export default createStore(initialState, {

  [LOGIN_SUCCESS]: (state, action) => {

    state.isAuthenticated = true
    state.email = action.email

    return state

  },

  [LOGIN_FAILURE]: (state, action) => {
    return setAuthenticated(state)
  },

  [LOGOUT]: (state, action) => {
    return setAuthenticated(state)
  }
})

Then state.isAuthenticated will change to false. But Connector component does not render component "UserFooter" inside.

UserFooter component:

export default (React) => {

  let types = React.PropTypes

  let UserFooter = (props) => {

    console.log('props', props)

    return {

      __proto__: React.Component.prototype,
      props,

      logout (e) {

        e.preventDefault()

        this.props.logout()

      },

      render () {

        let {isAuthenticated, email} = this.props.userFooter

        console.log('render', isAuthenticated)

        return (
          <div>

            {isAuthenticated ? (
              <p>
                Logged as : {email}
                <br/>
                <a onClick={(e) => this.logout(e) }>Sign Out</a>
              </p>

            ) : (
              <Link to='login'>Sign In</Link>
            )}

          </div>
        )
      }
    }
  }

  UserFooter.propTypes = {
    // isAuthenticated: types.bool.isRequired,
    // email: types.string,
    userFooter: types.object.isRequired,
    logout: types.func.isRequired
  }

  return UserFooter

}

Last thing: Amazing work mate!

@gaearon
Copy link
Contributor

gaearon commented Jun 7, 2015

I agree it's not very clear from the README, but Redux makes a hard assumption that you never mutate the state. Mutating the states defeats the purpose of Redux, and it's easy to avoid mutating it, so it's in fact a net good that the mutating code breaks early.

We should make it explicit in the docs.

Here's how your Store could look instead:

const initialState = {
  isAuthenticated: false,
  email: ''
}

let setAuthenticated = (state) => {
  return {
    isAuthenticated: false,
    ...state
  }
}

export default createStore(initialState, {

  [LOGIN_SUCCESS]: (state, action) => {
    return {
      isAuthenticated: true,
      email: action.email,
      ...state
    }
  },

  [LOGIN_FAILURE]: (state, action) => {
    return setAuthenticated(state)
  },

  [LOGOUT]: (state, action) => {
    return setAuthenticated(state)
  }
})

Does this solve your problem?

@gaearon
Copy link
Contributor

gaearon commented Jun 7, 2015

(Suggestion: maybe deep freeze the state atom in development mode?)

@gaearon
Copy link
Contributor

gaearon commented Jun 7, 2015

I added this to FAQ:

https://github.com/gaearon/redux/blob/master/README.md#my-views-arent-updating

Let me know if I missed something!

@gaearon gaearon closed this as completed Jun 7, 2015
@ooflorent
Copy link
Contributor

I think I've heard that Facebook will freeze props and maybe state when NODE_ENV isn't production. You should do the same.

@ooflorent
Copy link
Contributor

Another option is to clone the state in dev before injecting it to the component.

@jsifalda
Copy link
Author

jsifalda commented Jun 7, 2015

Much better! Thank you very much! :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants