关于没有中间件的 Redux Async (redux-thunk, redux-saga...)
About Redux Async without middleware (redux-thunk, redux-saga... )
有些动作有异步功能,比如fetch。但是,我不想使用像 redux-thunk 或 redux-saga 这样的中间件。
所以,我犹豫要不要使用这个代码。
/* actions */
...
export const fetchRequest = ({category, query, dispatch}) => ({
type: actionTypes.FETCH_REQUEST,
promise:
fetch(`${API_URL}${category}?${query}`, {headers: headers})
.then(response => response.json())
.then(data => dispatch(fetchRecieve(data))),
})
export const fetchRecieve = data => ({
type: actionTypes.FETCH_RECIEVE,
data,
})
...
/* In x.jsx */
...
const mapDispatchToProps = dispatch => ({
onClick: (category, query) => dispatch(fetchRequest({category, query, dispatch}))
})
...
此代码是否违反了 Redux 范式?
Redux FAQ "How can I represent “side effects” such as AJAX calls?..
In general, Redux suggests that code with side effects should be part of the action creation process. While that logic can be performed inside of a UI component, it generally makes sense to extract that logic into a reusable function so that the same logic can be called from multiple places—in other words, an action creator function.
您发布的函数是动作创建者,因此放置它们似乎是一个合适的地方,但是在下一段中他们说:
The simplest and most common way to do this is to add the Redux Thunk middleware that lets you write action creators with more complex and asynchronous logic. Another widely-used method is Redux Saga which lets you write more synchronous-looking code using generators, and can act like “background threads” or “daemons” in a Redux app. Yet another approach is Redux Loop, which inverts the process by allowing your reducers to declare side effects in response to state changes and have them executed separately. Beyond that, there are many other community-developed libraries and ideas, each with their own take on how side effects should be managed.
你有什么理由反对使用 redux-thunk、redux-saga、redux-loop 等吗?它们的存在都是为了真正帮助你。您可以选择手动执行副作用,但在 IMO 中使用中间件执行它的管理较少。
将 dispatch
注入到您的 action creator 中并根据需要使用它是完全没问题的。
如果您计划在不同的地方重用这些逻辑,那么将更多逻辑从您的组件外包到您的操作(或您的中间件)中实际上是一件好事。是completely legit that the logic inside your actions may also include async operations (as in your case) that postpone a dispatch or operations that dispatch several other actions. In case of redux-thunk this is called composition.
与 "redux-thunk-way" 相比,您的解决方案在某种程度上是 "shortcut",您的 thunk 将首先穿过中间件,然后控制将立即被 redux-thunk 反转。使用 redux-thunk,除了 dispatch
之外,您还可以获得注入 getState
的好处,这使您可以直接访问整个商店(没有 redux-thunk,您将不得不求助于 mergeProps 在你的组件中可以同时访问商店和调度)。
此外,dispatch
与您的操作的绑定使用 redux-thunk 更加标准化,它使用柯里化,因此您的 mapDispatchToProps
中的样板代码会更少并且看起来更干净(因为您这样做不必每次都自己注射 dispatch
)。
有些动作有异步功能,比如fetch。但是,我不想使用像 redux-thunk 或 redux-saga 这样的中间件。 所以,我犹豫要不要使用这个代码。
/* actions */
...
export const fetchRequest = ({category, query, dispatch}) => ({
type: actionTypes.FETCH_REQUEST,
promise:
fetch(`${API_URL}${category}?${query}`, {headers: headers})
.then(response => response.json())
.then(data => dispatch(fetchRecieve(data))),
})
export const fetchRecieve = data => ({
type: actionTypes.FETCH_RECIEVE,
data,
})
...
/* In x.jsx */
...
const mapDispatchToProps = dispatch => ({
onClick: (category, query) => dispatch(fetchRequest({category, query, dispatch}))
})
...
此代码是否违反了 Redux 范式?
Redux FAQ "How can I represent “side effects” such as AJAX calls?..
In general, Redux suggests that code with side effects should be part of the action creation process. While that logic can be performed inside of a UI component, it generally makes sense to extract that logic into a reusable function so that the same logic can be called from multiple places—in other words, an action creator function.
您发布的函数是动作创建者,因此放置它们似乎是一个合适的地方,但是在下一段中他们说:
The simplest and most common way to do this is to add the Redux Thunk middleware that lets you write action creators with more complex and asynchronous logic. Another widely-used method is Redux Saga which lets you write more synchronous-looking code using generators, and can act like “background threads” or “daemons” in a Redux app. Yet another approach is Redux Loop, which inverts the process by allowing your reducers to declare side effects in response to state changes and have them executed separately. Beyond that, there are many other community-developed libraries and ideas, each with their own take on how side effects should be managed.
你有什么理由反对使用 redux-thunk、redux-saga、redux-loop 等吗?它们的存在都是为了真正帮助你。您可以选择手动执行副作用,但在 IMO 中使用中间件执行它的管理较少。
将 dispatch
注入到您的 action creator 中并根据需要使用它是完全没问题的。
如果您计划在不同的地方重用这些逻辑,那么将更多逻辑从您的组件外包到您的操作(或您的中间件)中实际上是一件好事。是completely legit that the logic inside your actions may also include async operations (as in your case) that postpone a dispatch or operations that dispatch several other actions. In case of redux-thunk this is called composition.
与 "redux-thunk-way" 相比,您的解决方案在某种程度上是 "shortcut",您的 thunk 将首先穿过中间件,然后控制将立即被 redux-thunk 反转。使用 redux-thunk,除了 dispatch
之外,您还可以获得注入 getState
的好处,这使您可以直接访问整个商店(没有 redux-thunk,您将不得不求助于 mergeProps 在你的组件中可以同时访问商店和调度)。
此外,dispatch
与您的操作的绑定使用 redux-thunk 更加标准化,它使用柯里化,因此您的 mapDispatchToProps
中的样板代码会更少并且看起来更干净(因为您这样做不必每次都自己注射 dispatch
)。