【问题标题】:ShouldComponentUpdate is never called in child components永远不会在子组件中调用 ShouldComponentUpdate
【发布时间】:2018-11-04 04:58:13
【问题描述】:

我有两个组件。一个是父组件(连接到 redux 的智能组件),另一个是在数组迭代中呈现的子组件。

每当从子组件调度某些 redux 操作时,存储中的状态都会更改,并且整个元素列表会重新渲染,但我只想渲染实际状态已更改的子组件。就像在一个位置数组中一样,我想在特定位置显示加载器,并且数组中的对象更新得很好,但是为什么 shouldComponentUpdate 在子节点中不可用,以便我可以决定它是否应该渲染。

父组件

import React                        from 'react';
import { connect }                  from 'react-redux';
import { createStructuredSelector } from 'reselect';

class Locations extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return this.props.locations.map((location) => 
    <Location
      toggleLocationStatusInfo={this.props.toggleLocationStatusInfo}
      location={location} />)
  }
}

const mapDispatchToProps = (dispatch) => ({
  fetchLocations: (data) => dispatch(actions.fetchLocations(data)),
  toggleLocationStatusInfo: dispatch(actions.toggleLocationStatusInfo()),
});

const mapStateToProps = createStructuredSelector({
  locations: selectors.getLocations(),
});

export default connect(mapStateToProps, mapDispatchToProps)(Locations);

子组件

import React from 'react';
class Location extends React.Component {
  constructor(props) {
    super(props);
  }

  shouldComponentUpdate() {
    // THIS METHOD IS NEVER CALLED EVEN THE TOGGLE ACTION IS
    // DISPATCHCED AND REDUX STATE IS CHANGED. IT IS CALLED FINE FINE
    // PARENT (Locations) COMPONENT BUT NOT HERE
  }

  render() {
    // render this.props.location content here
    // One of my anchor calls onClick={this.props.toggleLocationStatusInfo}
  }
}

Location.propTypes = {
  location: React.PropTypes.object
  toggleLocationStatusInfo: React.PropTypes.func,
}

我怎样才能知道为什么在子进程中不调用 shouldComponentUpdate?

【问题讨论】:

  • 这只是一个猜测,但可能是因为数组中的位置没有键,所以它们本身从未真正得到 更新,只是被抛出每次都重新渲染
  • 非常感谢哈姆斯。这解决了我的问题。

标签: reactjs redux react-redux


【解决方案1】:

我忘了在每个组件上添加一个唯一键,所以每次都只是创建新的子组件。

在 Location 上添加 key prop 后,效果很好。

【讨论】:

    【解决方案2】:

    如果您使用 react-router 中的 Route 并传递内联函数而不是组件,则会出现同样的问题,如下所示:

    问题

    <Route
      path="/decrement"
      component={() => (
        <Decrement decrementBy={decrementBy} isLoading={isLoading} />
      )}
    />
    
    

    解决方案

    <Route
      path="/decrement"
      render={() => (
        <Decrement decrementBy={decrementBy} isLoading={isLoading} />
      )}
    />
    
    

    <Route path="/decrement">
        <Decrement decrementBy={decrementBy} isLoading={isLoading} />
    </Route>
    
    

    【讨论】:

    • 为什么这个答案不在顶部?在搜索了 5 个小时后找到了这个,这就像一个魅力。
    猜你喜欢
    • 2018-11-16
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    • 2014-11-01
    相关资源
    最近更新 更多