React Redux - 在mapStateToProps中返回的状态是将reducer名称作为属性吗?

nuw*_*way 17 redux react-redux

我有2个减速器组合在Root Reducer中,并在商店中使用.第一个reducer'MisscksReducer'应该返回一个对象,第二个'FavoritesReducer'应该返回一个数组.

当我在连接中创建容器组件和mapStateToProps方法时,由于某种原因,存储的返回状态是一个对象,其中包含2个包含数据的reducer对象,而不仅仅是包含重叠数据的对象,如预期的那样.

    function mapStateToProps(state) {
       debugger:
       console.dir(state)
       //state shows as an object with 2 properties, AllTracksReducer and       FavoritesReducer. 


        return {
            data: state.AllTracksReducer.data,
            isLoading: state.AllTracksReducer.isLoading
        }
    }

export default connect(mapStateToProps)(AllTracksContainer);
Run Code Online (Sandbox Code Playgroud)

所以,在mapStateToProps中,要获得正确的状态属性,我必须说state.AllTracksReducer.data ...但是我期待数据直接在状态对象上可用?

mar*_*son 12

是的,这是一个常见的半错误.这是因为您正在使用可能使用ES6对象文字缩写语法来创建传递给的对象combineReducers,因此导入变量的名称也用于定义状态切片名称.

Redux文档中的结构化减速器 - 使用中combineReducers解释了此问题.

  • 错误是尝试使用 ES6 对象字面量简写,并直接传入导入的 reducer 名称,例如 `combineReducers({userReducer})`。这将导致 `state.userReducer`。根据链接的文章,在状态切片名称中包含“reducer”被认为是不好的做法。更好的方法是`combineReducers({users : userReducer})`。 (2认同)

Cha*_*own 5

Create some selectors that receive the whole state (or the reducer-specific state) and use it in your mapStateToProps function. Indeed the name you define when you combineReducers will be the topmost state keys, so your selectors should take that into account:

const getTracks = (state) => state.allTracks.data
const isLoading = state => state.allTracks.isLoading
Run Code Online (Sandbox Code Playgroud)

This assumes you combine your reducers with allTracks as they key like here:

combineReducers({
  allTracks: allTracksReducer
})
Run Code Online (Sandbox Code Playgroud)

And then you can use those selectors in your mapper, like

const mapStateToProps = state => ({
  isLoading: isLoading(state),
  tracks: getTracks(state)
})
Run Code Online (Sandbox Code Playgroud)

There's a delicate link between your combineReducers call and your selectors. If you change the state key name you'll have to update your selectors accordingly.

It helps me to think of action creators as "setters" and selectors as "getters", with the reducer function being simply the persistence part. You call your setters (dispatching action creators) when you want to modify your state, and use your selectors as shown to get the current state and pass it as props to your components.


Sea*_*won 3

嗯,这就是它应该如何工作的。当您使用combineReducers 时,您实际上是将reducer 的名称映射到reducer 函数。

如果它困扰你,如果你使用 es2016(尽管看起来你没有),我建议你使用一些语法魔法,如下所示:

function mapStateToProps(state) {
    const { data, isLoading } = state.allTracksReducer;
    return {
        data: data,
        isLoading: isLoading
    }
}

export default connect(mapStateToProps)(AllTracksContainer);
Run Code Online (Sandbox Code Playgroud)

请记住,状态是拥有所有减速器的事实来源之一。