7
votes

In React Native and Redux, I have a <NavigationCardStack/> as a root component. And every time state has been updated, the redux-logger updates correctly with the next/new state.

And after the state change, when newly updated state is console logged in a child component, it doesn't console log the updated state but rather console logs the initial state (in the child component childPage.js and logging: render(){ console.log(this.props.state) return(...) ...).

Could it be that I am hooked up to Redux incorrectly or missing something? Because, everything seem to work perfectly fine and makes sense.

Thank you in advance!

Here are some snippets of my code:

This is my reducer and the child component would just log the initialState here even though other properties have been added and updated:

const initialState = {
  meetUp: false,
}

function itemReducer(state = initialState, action) {
  switch(action.type) {


    case ITEM_QUANTITY:
      return {
        ...state,
        quantity: action.quantity
      }

    case ITEM_PRICE:
      return {
        ...state,
        price: action.price
      }

    case ITEM_MEET_UP:
      return {
        ...state,
        meetUp: action.meetUp
      }

     default:
       return state
  }
}

export default itemReducer

And connected to the root component like so:

function mapStateToProps(state) {
  return {
    itemInfo: state.itemReducer,
    ...
  }
}

export default connect(
  mapStateToProps,
  {
    itemQuantity: (value) => itemQuantity(value),
    itemPrice: (value) => itemPrice(value),
    itemMeetUp: (value) => itemMeetUp(value),
  }
)(NavigationRoot)

With following actions:

export function itemMeetUp(value) {
  return {
    type: ITEM_MEET_UP,
    meetUp: value
  }
}

export function itemQuantity(value) {
  return {
    type: ITEM_QUANTITY,
    quantity: value
  }
}

export function itemPrice(value) {
  return {
    type: ITEM_PRICE,
    price: value
  }
}

state={this.props} represent the state and how it is supposed to be passed down to child components

  _renderScene (props) {
    const { route } = props.scene

    return (
      <route.component _handleNavigate={this._handleNavigate.bind(this)} state={this.props}/>
    )
  }

    <NavigationCardStack
      renderScene={this._renderScene}
      ...
    />
2
Its hard to tell from the snippets provided - any chance of putting up a github repo or jsfiddle? - Chris
Out of curiosity, what happens when you try to console.log from the componentWillReceiveProps(props) lifecycle method in your childPage.js component? Is that method ever getting called? If so, can you log the props argument to determine if the component is ever receiving the correct properties? - bryonbean
@bryonbean I did console log as constructor(props) { super(props) console.log(props) and it does print out all the initial properties the very first time the page gets rendered. But then after being updated, the console log never gets called again, so it is never being re-rendered again despite the update on the state, correct? - Jo Ko
No, the constructor will only get called once upon instantiation and this is where the initial/original properties get set. Subsequent re-rendering of the component's properties can be determined by adding a lifecycle method called componentWillReceiveProps(props). Inside this method you can call console.log(props) to determine what new properties are being set on the component. (see: facebook.github.io/react/docs/component-specs.html) - bryonbean
@bryonbean I tried it inside render() { console.log(props) return()}, and when the state gets updated, the console logs again but rather than the updated state, it console logs the initial state. And I tried componentWillReceiveProps(props) { console.log(props) } before render(){return()} but never gets called and does not console log - Jo Ko

2 Answers

2
votes

Could this issue be related? It seems similar in that NavigationCardStack won't update even though the redux state changes, and redux-logger logs the change. I can't tell from your code sample, but one way to test this might be to connect the children or one child directly to your redux store instead of having NavigationCardStack pass the store state in as props? That github issue above also has some hacky workarounds, but I'm not very familiar with react-native so I can't be much help there.

1
votes

This is basically a stab in the dark and based entirely on our conversation in the comments, but is the _renderScene method bound to the component in the constructor? E.g:

constructor (props) {
  super(props)
  ...
  this._renderScene = this._renderScene.bind(this);
}