为什么 redux 在其 applyMiddleware 实现中执行 `{... store}`?
Why does redux do `{... store}` in its applyMiddleware implementation?
Although this is about the applyMiddleware
implementation I accept this being a duplicate of the question referring to the spreading operator as the core of the mental issue is exactly that.
序言:
我不喜欢魔法,因为它实际上并不清楚事情为什么会发生。所以我在寻找实际的 redux 实现。
有什么问题?
好吧,我在 applyMiddleware
的实现中看到了这一点:
import compose from './compose'
/**
* Creates a store enhancer that applies middleware to the dispatch method
* of the Redux store. This is handy for a variety of tasks, such as expressing
* asynchronous actions in a concise manner, or logging every action payload.
*
* See `redux-thunk` package as an example of the Redux middleware.
*
* Because middleware is potentially asynchronous, this should be the first
* store enhancer in the composition chain.
*
* Note that each middleware will be given the `dispatch` and `getState` functions
* as named arguments.
*
* @param {...Function} middlewares The middleware chain to be applied.
* @returns {Function} A store enhancer applying the middleware.
*/
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
const store = createStore(reducer, preloadedState, enhancer)
let dispatch = store.dispatch
let chain = []
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
return {
...store,
dispatch
}
所以它实际上是将整个商店分布在商店对象的第一层。但我们只是想应用中间件,并没有实际操作商店。
那么为什么不做下面的事情呢?
return {
store,
dispatch
}
在这个非常具体的实现中/在使用它的应用程序范围内,store
超过 ...store
会产生什么副作用?
用 store
代替 ...store
会完全改变表达式的含义。
{store, dispatch}
等同于:{store: store, dispatch: dispatch}
而 {...store, dispatch}
表示 expanding/merging 原始 store
对象与新的 dispatch
属性.
详细阅读 here 传播语法。
我从来没有机会用 React
做项目,但我确实看过一些视频,我知道框架的想法是 store
是 不可变(阅读有关不可变性的更多信息here), the three dots are called Spread syntax and I think that this syntax is used in shorthand instead of Object.assign
The Rest/Spread Properties for ECMAScript proposal (stage 3) adds
spread properties to object literals. It copies own enumerable
properties from a provided object onto a new object.
Shallow-cloning (excluding prototype) or merging of objects is now
possible using a shorter syntax than Object.assign.
如果将 ...store
更改为 store
,您将彻底改变框架的行为。我不知道具体的副作用是什么,我们需要做一些测试:)
希望这对您更好地理解这段代码有所帮助。祝你好运!
{...store, dispatch}
与 Object.assign({}, store, {dispatch: dispatch})
相同。
{store, dispatch}
等同于 {store: store, dispatch: dispatch}
.
如果您不知道 Object.assign
的作用:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
结果是如果在对象store
上存在一些属性foo
,在新创建的对象o
上,在第一种情况下你访问它通过 o.foo
,在第二种情况下通过 o.store.foo
.
所以这真的很重要 ;)
在您了解它们的用途之前,这些符号看起来 "magical"。然后你开始觉得他们为你节省了很多时间,让你写出 DRY 和简短的代码。
Although this is about the
applyMiddleware
implementation I accept this being a duplicate of the question referring to the spreading operator as the core of the mental issue is exactly that.
序言:
我不喜欢魔法,因为它实际上并不清楚事情为什么会发生。所以我在寻找实际的 redux 实现。
有什么问题?
好吧,我在 applyMiddleware
的实现中看到了这一点:
import compose from './compose'
/**
* Creates a store enhancer that applies middleware to the dispatch method
* of the Redux store. This is handy for a variety of tasks, such as expressing
* asynchronous actions in a concise manner, or logging every action payload.
*
* See `redux-thunk` package as an example of the Redux middleware.
*
* Because middleware is potentially asynchronous, this should be the first
* store enhancer in the composition chain.
*
* Note that each middleware will be given the `dispatch` and `getState` functions
* as named arguments.
*
* @param {...Function} middlewares The middleware chain to be applied.
* @returns {Function} A store enhancer applying the middleware.
*/
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
const store = createStore(reducer, preloadedState, enhancer)
let dispatch = store.dispatch
let chain = []
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
return {
...store,
dispatch
}
所以它实际上是将整个商店分布在商店对象的第一层。但我们只是想应用中间件,并没有实际操作商店。
那么为什么不做下面的事情呢?
return {
store,
dispatch
}
在这个非常具体的实现中/在使用它的应用程序范围内,store
超过 ...store
会产生什么副作用?
用 store
代替 ...store
会完全改变表达式的含义。
{store, dispatch}
等同于:{store: store, dispatch: dispatch}
而 {...store, dispatch}
表示 expanding/merging 原始 store
对象与新的 dispatch
属性.
详细阅读 here 传播语法。
我从来没有机会用 React
做项目,但我确实看过一些视频,我知道框架的想法是 store
是 不可变(阅读有关不可变性的更多信息here), the three dots are called Spread syntax and I think that this syntax is used in shorthand instead of Object.assign
The Rest/Spread Properties for ECMAScript proposal (stage 3) adds spread properties to object literals. It copies own enumerable properties from a provided object onto a new object.
Shallow-cloning (excluding prototype) or merging of objects is now possible using a shorter syntax than Object.assign.
如果将 ...store
更改为 store
,您将彻底改变框架的行为。我不知道具体的副作用是什么,我们需要做一些测试:)
希望这对您更好地理解这段代码有所帮助。祝你好运!
{...store, dispatch}
与 Object.assign({}, store, {dispatch: dispatch})
相同。
{store, dispatch}
等同于 {store: store, dispatch: dispatch}
.
如果您不知道 Object.assign
的作用:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
结果是如果在对象store
上存在一些属性foo
,在新创建的对象o
上,在第一种情况下你访问它通过 o.foo
,在第二种情况下通过 o.store.foo
.
所以这真的很重要 ;)
在您了解它们的用途之前,这些符号看起来 "magical"。然后你开始觉得他们为你节省了很多时间,让你写出 DRY 和简短的代码。