【问题标题】:React Native & Redux: Why aren't child components re-rendering on every state update?React Native 和 Redux:为什么子组件不会在每次状态更新时重新渲染?
【发布时间】:2017-01-14 05:38:42
【问题描述】:

在 React Native 和 Redux 中,我有一个 <NavigationCardStack/> 作为根组件。并且每次更新状态时,redux-logger 都会正确更新下一个/新状态。

并且在状态改变之后,当新更新的状态是控制台登录子组件时,它不会控制台记录更新的状态,而是控制台记录初始状态(在子组件中childPage.js 和日志记录:@987654324 @)。

可能是我错误地连接到 Redux 或遗漏了什么?因为,一切似乎都运行良好且有意义。

提前谢谢你!

这是我的代码的一些 sn-ps:

这是我的 reducer,即使添加和更新了其他属性,子组件也会在此处记录 initialState:

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

并像这样连接到根组件:

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

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

通过以下操作:

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} 表示状态以及它应该如何传递给子组件

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

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

    <NavigationCardStack
      renderScene={this._renderScene}
      ...
    />

【问题讨论】:

  • 很难从所提供的 sn-ps 中看出 - 有没有机会建立一个 github repo 或 jsfiddle?
  • 出于好奇,当您尝试从 childPage.js 组件中的 componentWillReceiveProps(props) 生命周期方法访问 console.log 时会发生什么?该方法是否被调用过?如果是这样,您能否记录 props 参数以确定组件是否接收到正确的属性?
  • @bryonbean 我将控制台日志记录为constructor(props) { super(props) console.log(props),它确实在页面第一次呈现时打印出所有初始属性。但是在更新之后,控制台日志不再被调用,因此尽管状态更新,它也永远不会被重新渲染,对吗?
  • 不,构造函数只会在实例化时被调用一次,这是设置初始/原始属性的地方。组件属性的后续重新渲染可以通过添加一个名为componentWillReceiveProps(props) 的生命周期方法来确定。在此方法中,您可以调用console.log(props) 来确定在组件上设置了哪些新属性。 (见:facebook.github.io/react/docs/component-specs.html)
  • @bryonbean 我在render() { console.log(props) return()} 内部尝试过,当状态更新时,控制台会再次记录,但不是更新状态,而是控制台记录初始状态。我在render(){return()} 之前尝试过componentWillReceiveProps(props) { console.log(props) },但从未被调用,也没有控制台日志

标签: javascript html reactjs react-native redux


【解决方案1】:

this issue 可能有关联吗?看起来很相似,NavigationCardStack 不会更新,即使 redux 状态发生变化,redux-logger 也会记录变化。我无法从您的代码示例中看出,但一种测试方法可能是 connect 孩子或一个孩子直接到您的 redux 商店,而不是让 NavigationCardStack 将商店状态作为道具传递?上面那个 github issue 也有一些 hacky 的解决方法,但是我对 react-native 不是很熟悉,所以在那里我帮不上什么忙。

【讨论】:

  • connect 不建议将所有孩子直接加入redux,这不是一个好习惯吗?
  • 这并不是真正的坏习惯。如果您非常关心性能,那么您绝对应该自己检测和查看,但我最近看到的时尚做法是将组件树连接到尽可能低的位置,并且只映射您需要的道具。至少它使在层次结构中移动组件变得不那么乏味。
  • 但这不是违背了 redux 的目的吗?您只想将其保持在一个流程中?
  • 这并没有违背 redux 的目的。主要目的是您的所有状态都来自一个中心位置。让许多组件访问单个商店并不是一个坏习惯,如果您有多个不同的商店并且访问它们的方式不一致,就会出现毛茸茸的情况。这在principles section of the very excellent redux docs 中得到了更好的总结。 This other section 也与此对话相关,并且很有启发性。希望有帮助!
【解决方案2】:

这基本上是在黑暗中刺探,完全基于我们在 cmets 中的对话,但是 _renderScene 方法是否绑定到构造函数中的组件?例如:

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

【讨论】:

  • 不用担心,但是是的,我确实将方法绑定到构造函数中的组件。
  • @JoKo 没有看到更多你的代码是如何构造的,我很茫然,但我可以自信地告诉你,就你的子组件而言,this.props 的值永远不会改变;如果确实如此,componentWillReceiveProps 方法将触发,您将能够在那里记录它们。这意味着您的父组件也没有看到变化。希望我能提供更多帮助。
  • 我也很茫然。我总是可以提供更多的代码。您可能需要哪一部分?
  • 签到看看你是否看过我的最后一个例子。请告诉我。
  • 对不起,我没有早点看到这个。我猜&lt;NavigationCardStack ... /&gt; 的代码 sn-p 是根组件?很高兴看到它的全部以及你所有的 Redux 代码。还有一件事,这种风格/代码看起来很熟悉,是不是基于某处的教程?
猜你喜欢
  • 1970-01-01
  • 2018-12-12
  • 2018-06-04
  • 2021-06-22
  • 2020-03-03
  • 1970-01-01
  • 1970-01-01
  • 2020-03-10
  • 2020-11-04
相关资源
最近更新 更多