React Native 和 Redux:为啥子组件不会在每次状态更新时重新渲染?

Posted

技术标签:

【中文标题】React Native 和 Redux:为啥子组件不会在每次状态更新时重新渲染?【英文标题】: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) ,但从未被调用,也没有控制台日志 【参考方案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 代码。还有一件事,这种风格/代码看起来很熟悉,是不是基于某处的教程?

以上是关于React Native 和 Redux:为啥子组件不会在每次状态更新时重新渲染?的主要内容,如果未能解决你的问题,请参考以下文章

Wix React-Native-Navigation v2 和 redux-persist

React Native - Redux 不会立即更新

React Native 已经有了异步存储。为啥我应该在我的 react native 应用中使用 Redux 和 Redux Thunk?

React native 和 redux 仍然无法正常工作

React Native 和 Redux 我应该每个场景/路线都有一个商店吗?

React-Native 开发 在react-native 中 运用 redux