首页 > 解决方案 > 通过容器传递函数以导出状态

问题描述

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

// 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 存储中派生状态的函数,出于性能原因,可以在某些事件挂钩中调用该函数。例如,如果它们选择了任何项目,我需要有条件地打开一个模式。它将像这样实现。

onDrop = () => {
  // if there are any selected at all,
  // open a modal for the user.
  const selected = this.props.getSelected();
  if (selected.length) {
    this.openMoveRequestModal();
  }
}

我可以通过一种非常丑陋的方法让它“工作”。

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容器派生状态的函数?

标签: javascriptreactjsreduxreact-redux

解决方案


组件通常无法访问整个存储状态,因为这对性能不利。如果从函数返回整个存储状态,组件将在每个mapState分派的操作上重新渲染,而不仅仅是在它真正需要的数据发生更改时。

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

  • 提取额外的信息并将其mapState与组件实际需要渲染的数据一起返回
  • 将该逻辑移出到一个 thunk 函数中,该函数可以访问getState.

我建议使用 thunk。

例子:

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);

推荐阅读