在 action creator 中获取状态的 Redux 模式

Redux pattern for getting state in action creator

我已经确定了 2 种在 action creator 中获取状态的模式,我想知道哪种模式更好:

  1. 使用 redux-thunk 和 getState
  2. 组件中的 mapStateToProps 并在调用 action creator 时将状态传回 Redux

每个示例:

class SomeComponent {
    render() {
        return (
            <Button onPress={this.props.networkCall}/>
        )
    }
}

const mapDispatchToProps = {
    networkCall: actions.networkCall,
}

export default connect(undefined, mapDispatchToProps)(SomeComponent)

export networkCall() {
    return (dispatch, getState) => {
        const { dataForNetworkCall } = getState().someReducer
        dispatch(pending())
        axios.get(`something/${dataForNetworkCall}/something2`)
            .then(() => {
                dispatch(success())
            }
            ...
    }
}


class SomeComponent {
    render() {
        const { networkCall, dataForNetworkCall } = this.props
        return (
            <Button onPress={networkCall(dataForNetworkCall)}/>
        )
    }
}

function mapStateToProps(state) {
    const { dataForNetworkCall } = state.someReducer
    return { dataForNetworkCall }
}

const mapDispatchToProps = {
    networkCall: actions.networkCall,
}

export default connect(mapStateToProps, mapDispatchToProps)(SomeComponent)

export networkCall(dataForNetworkCall) {
    return (dispatch) => {
        dispatch(pending())
        axios.get(`something/${dataForNetworkCall}/something2`)
            .then(() => {
                dispatch(success())
            }
            ...
    }
}

我觉得 2 是个坏主意,因为它涉及将状态传递给组件只是为了将其传递回 Redux。不过网上好像有很多文章说选项1是反模式(包括Dan Abramov himself saying it is an anti-pattern)。那么,"best"方法是什么?

我总是遵循后一个例子,这意味着我的动作创建者不依赖于 store。但是,有一种情况,我必须将用户令牌传递给几乎所有需要与服务器交互的操作 API。我没有将它重复传递给每个动作创建者或在 getState() 中访问它,而是编写了一个自定义中间件(并不难),它可以识别这些动作并使用另一个名为 userToken.[=23 的道具来丰富它们=]

回到 Dan Abramov 的回答。他在评论中说:

It’s fine to read from the store in the action creator.

这让我感到困惑,但我认为他的意思是出于某些原因可以这样做:

I think it’s acceptable is for checking cached data before you make a request, or for checking whether you are authenticated (in other words, doing a conditional dispatch)

... 并且使用 getState 可能会导致以下情况:

... it is hard to trace where those incorrect values come from because they are already part of the action, rather than directly computed by a reducer in response to an action.

我认为他的意思是 action creator 不应该传递被 reducer 替换的 store 的更新部分,但 action 应该描述正在发生的事情并且 reducer 应该处理更新:

不是:

here is the new item list - replace it in the store

但是:

we need to remove the item with id: 5 - handle it

...这与从商店访问值以在请求中使用它有点不同。我advice you to read the linked blog。它深入回答了您的问题,并且有一些关于什么是最好的例子的争论。 TL;DR - 争论哪种方法更好。