在 action creator 中获取状态的 Redux 模式
Redux pattern for getting state in action creator
我已经确定了 2 种在 action creator 中获取状态的模式,我想知道哪种模式更好:
- 使用 redux-thunk 和 getState
- 组件中的 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 - 争论哪种方法更好。
我已经确定了 2 种在 action creator 中获取状态的模式,我想知道哪种模式更好:
- 使用 redux-thunk 和 getState
- 组件中的 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 - 争论哪种方法更好。