首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >传递函数通过容器导出状态

传递函数通过容器导出状态
EN

Stack Overflow用户
提问于 2018-05-02 14:47:24
回答 2查看 38关注 0票数 0

我有一个容器,目前的结构如下:

代码语言:javascript
运行
复制
// container.ts
import { connect } from 'react-redux';
import { selectItems } from './actions';
import { selectSelectedItems } from './selectors';
import component from './component';

const mapStateToProps = (state: AppState) => ({
  selected: selectSelectedItems(state),
});

const mapDispatchToProps = {
  select: selectItems,
}

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

但是,在这种情况下,每当选择发生变化时,组件的每个实例都会更新。

我真正需要的是一个从redux存储派生状态的函数,在某些情况下,出于性能原因,可以调用redux存储库。例如,我需要有条件地打开一个模式,如果他们与任何选择的项目。它将像这样实施。

代码语言:javascript
运行
复制
onDrop = () => {
  // if there are any selected at all,
  // open a modal for the user.
  const selected = this.props.getSelected();
  if (selected.length) {
    this.openMoveRequestModal();
  }
}

我可以用一种很难看的方法让它“工作”。

代码语言:javascript
运行
复制
export default class ProductGrid extends React.PureComponent<Props> {
  static contextTypes = { store: PropTypes.object };

  onDrop = () => {
    const state = this.context.store.getState();
    // do whatever here
  }
}

但理想情况下,我将能够传递一个函数引用,它将从我的redux存储中派生出状态。

是否可以通过react-redux容器传递派生状态的函数?

EN

回答 2

Stack Overflow用户

发布于 2018-05-02 15:39:02

组件通常不能访问整个存储状态,因为这不利于性能。如果从mapState函数返回整个存储状态,则组件将对每个分派的操作重新呈现,而不仅仅是当它真正需要的数据发生变化时。

因此,如果您的组件需要访问状态的一个单独部分才能做出额外的决定,那么您有两个主要选择:

  • 提取额外的信息,并在mapState中返回它以及组件实际需要呈现的数据。
  • 将该逻辑移出到一个thunk函数中,该函数可以访问getState

我建议你用一次雷击。

示例:

代码语言:javascript
运行
复制
function openModalIfSelected() {
    return (dispatch, getState) => {
        const state = getState();

        const selected = selectSelectedItems(state);

        if(selected.length) {
            dispatch(openMoveRequestModal());
        }
    }
}

// later, in the component file

const actionCreators = {openModalIfSelected};

class ProductGrid extends Component {
    render() {
        return (
            <div>
                {/* all the normal rendering stuff here */}
                <DropTarget onDrop={this.props.openModalIfSelected} />
            </div>
        );
    }
}

export default connect(null, actionCreators)(ProductGrid);
票数 0
EN

Stack Overflow用户

发布于 2018-05-02 22:03:02

如果您知道在所有情况下都不需要在选择更改时重新呈现您的组件,那么如果只更改了所选内容,您就可以知道跳过重新呈现的反应:

代码语言:javascript
运行
复制
export default class ProductGrid extends React.PureComponent {
  static propTypes = {
    selected: PropTypes.array.isRequired,
    /* others... */
  }

  shouldComponentUpdate (nextProps, nextState) {
    // If any props other than "selected" changed, re-render.
    // Otherwise, if no props or only "selected" changed, skip the render.
    const changedProps = getChangedProps(this.props, nextProps)
    changedProps.delete('selected')
    return changedProps.size > 0
  } 
}

function getChangedProps (currentProps, nextProps) {
  return new Set(
    Object.keys(currentProps)
      .filter(propName => currentProps[propName] !== nextProps[propName])
  )
}

shouldComponentUpdate是一种基于某种条件(道具和状态的属性)避免重呈现的机制。如果函数返回false,则组件将在获得新的道具或状态之前不会呈现--此时将再次调用shouldComponentUpdate

在实现shouldComponentUpdate时,性能是很重要的,因为它会在每个潜在呈现上被调用(也就是说,每当道具或状态更改时)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50137481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档