Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 使用React-Redux MapStateTrops的可重用组件_Reactjs_Redux_React Redux - Fatal编程技术网

Reactjs 使用React-Redux MapStateTrops的可重用组件

Reactjs 使用React-Redux MapStateTrops的可重用组件,reactjs,redux,react-redux,Reactjs,Redux,React Redux,React组件油桶连接my redux store以创建容器油桶容器: // ---- component class OilBarrel extends Component { render() { let data = this.props.data; ... } } // ---- container function mapStateToProps(state) { let data = state.oilbarrel.data; ... }

React组件
油桶
连接my redux store以创建容器
油桶容器

// ---- component

class OilBarrel extends Component {
  render() {
     let data = this.props.data;
     ...
  }
}

// ---- container

function mapStateToProps(state) {
  let data = state.oilbarrel.data;
  ...
}

const OilBarrelContainer = connect(mapStateToProps)(OilBarrel)

// ---- reducer

const oilbarrel = (state = {}, action) => {
  let data = state.data;
}

const storeFactory = (server = false, initialState = {}) => {
    return applyMiddleware(...middleware(server))(createStore)(
        combineReducers({oilbarrel, otherReducer1, otherReducer2}),
        initialState
    )
}
我觉得奇怪的是,
MapStateTrops()
接收顶级状态对象(应用程序的整个状态),要求我遍历
state.oilbarker.data
,而减速器(方便地)只接收属于此组件的状态分支


这限制了重用此容器的能力,而不知道它在状态层次结构中的位置。我的
MapStateTrops()
正在接收完整状态,这是我做错了什么吗?

否这是故意的,因为您可能希望在组件中使用状态的其他部分。一种选择是将选择器(mapStateToProps)保存在与组件分离的文件中,这将帮助您重用选择器。如果您的应用程序非常大且复杂,您还可以签出库,例如重新选择,这有助于您提高选择器的效率。

这就是
MapStateTops
行为。您必须将redux状态视为独立于您在项目中拥有的组件的唯一真相来源(顺便说一句,这就是它的真实情况)。没有出路,您必须准确地了解状态中特定数据的层次结构,才能将其传递给容器组件。

Dan Abramov在他的高级redux课程中提供了解决方案

其思想是,对于每个减速器,都有一个选择器,选择器只知道它的减速器结构。高级减速机的选择器、包装低级减速机的选择器以及它们的部分状态,等等

该示例取自本课程的:

在todos reducer文件中:

export const getVisibleTodos = (state, filter) => {
  switch (filter) {
    case 'all':
      return state;
    case 'completed':
      return state.filter(t => t.completed);
    case 'active':
      return state.filter(t => !t.completed);
    default:
      throw new Error(`Unknown filter: ${filter}.`);
  }
};
export const getVisibleTodos = (state, filter) =>
  fromTodos.getVisibleTodos(state.todos, filter);
在主减速器文件中:

export const getVisibleTodos = (state, filter) => {
  switch (filter) {
    case 'all':
      return state;
    case 'completed':
      return state.filter(t => t.completed);
    case 'active':
      return state.filter(t => !t.completed);
    default:
      throw new Error(`Unknown filter: ${filter}.`);
  }
};
export const getVisibleTodos = (state, filter) =>
  fromTodos.getVisibleTodos(state.todos, filter);

现在,您可以在不了解结构的情况下获取状态的每个部分。但是,它增加了很多样板。

组件的放置如何改变州层次结构?谢谢,如果我想在州层次结构的不同位置使用另一个OilBarrel组件,那么我必须为其创建一个新容器吗?为什么要在州的另一个位置放置另一个OilBarrel?油桶数组不适合这种情况?不适合。您可以渲染
,然后使用
mapState
中的
ownProps
参数根据该ID查找正确的值。