React Native/Redux: How to pass down updated state to child components every time state changes?

拟墨画扇 提交于 2019-12-25 07:44:15

问题


In React Native and Redux, I am using <NavigationCardStack/> as the root component and render routes with _renderScene(). But seems like whenever the root component re-renders with state update, it does not pass the state down every update, because I put console.log(this.props) in the child component and logs the passed state, but it only logs once and that is the first time the app starts up and never logs after even if the root component re-renders with the state update.

Why isn't it passing down the updated state every time the state changes? And why doesn't the child component re-render whenever the root component does?

This is my set up:

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

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

    <NavigationCardStack
      direction='horizontal'
      navigationState={this.props.navigation}
      onNavigate={this._handleNavigate.bind(this)}
      renderScene={this._renderScene}
      renderOverlay={this.renderOverlay}
      style={styles.container}
    />

In _renderScene, props alone logs:

And this.props logs the actually state passed down via Redux:

And in the child component childPage.js, I am simply logging like so, and it logs the props passed down (_handleNavigate and state) correctly but the state just continues to represent initial state even if it gets updated:

  render() {
    console.log(this.props.state)

    return (

Thank you in advance!

EDIT

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
  }
}

回答1:


There is only one reason that a child component does not render after a parent render - its shouldComponentUpdate method, or one from a component between it and the parent, has returned false. Often (particularly with Redux) shouldComponentUpdate methods are written to block the rerender if the properties haven't changed shallowly. Redux relies on you not mutating state, but instead always returning a new object with any changes from your reducer, otherwise the shouldComponentUpdate optimisation causes unexpected behaviour.

Could the problem be that you are modifying deep state rather than returning new objects? See http://redux.js.org/docs/basics/Reducers.html for more details.




回答2:


A first guess is that your NavigationCardStack isn't rerendering since it thinks the props being presented to it is unchanged. Try forcing a rerender (forceUpdate) and see what happens.



来源:https://stackoverflow.com/questions/39279531/react-native-redux-how-to-pass-down-updated-state-to-child-components-every-tim

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!