如何手动将操作分派到使用 configureStore 创建的商店?
How do I manually dispatch actions to a store created with configureStore?
我有一个项目,其中一半是用 classes 制作的,另一半是用 hooks 和 Redux 制作的。
为此,我使用 Redux Toolkit 中的 configureStore()
创建了一个商店,并使用 Provider
组件提供了它。以极简的方式,商店设置如下:
const userSlice = createSlice({
name: 'user',
initialState: {
user: {}
},
reducers: {
validate: (state, action) => state.user = action.payload
}
})
const store configureStore({
reducer: {
user: userSlice.reducer
}
})
有两个组件 - 一个新的,功能性的,它使用 useSelector()
钩子,和一个旧的,它基于 class,但需要使用这个 sasme 商店来调度一个行动。
为此,我导入商店并启动
store.dispatch({type: 'user/validate', payload: newUser});
来自 class 组件。
我没有收到任何错误,但什么也没有发生。
我从 DevTools 的 Redux 插件跟踪了我的输入,我可以看到状态没有改变,所以我假设我对 dispatch
的手动调用有些错误。
我期望发生的是状态更新,这将触发使用 useSelector
的组件的重新渲染
以下方法是一种安全的分派操作的方法,不会拼错类型字符串。
- 从reducer中提取action
const userSlice = createSlice({
name: 'user',
initialState: {
user: {}
},
reducers: {
validate: (state, action) => {
state.user = action.payload
}
}
})
// <------------------
// Action creators are generated for each case reducer function
export const { validate } = userSlice.actions
export const store = configureStore({
reducer: {
user: userSlice.reducer
}
})
- 按原样发送操作
store.dispatch(validate(newUser))
问题
我要说的是,问题是您正试图在 reducer 函数 和 中同时改变状态对象 return它。
In any given case reducer, Immer expects that you will either mutate
the existing state, or construct a new state value yourself and return
it, but not both in the same function!
解决方案
只是改变状态,不要return它。
reducers: {
validate: (state, action) => {
state.user = action.payload;
},
}
如果您希望基于 class 的组件订阅您的 redux 存储,那么您仍然可以使用来自 react-redux
.
的 connect 高阶组件
示例:
import { connect } from 'react-redux';
import { validate } from '../path/to/userSlice';
class MyComponent extends Component {
...
// In a function you can simply dispatch the validate action
// as it was wrapped in a call to dispatch already and injected
// as a prop.
this.props.validate(somePayloadValue);
...
}
const mapDispatchToProps = {
validate
};
export default connect(null, mapDispatchToProps)(MyComponent);
我有一个项目,其中一半是用 classes 制作的,另一半是用 hooks 和 Redux 制作的。
为此,我使用 Redux Toolkit 中的 configureStore()
创建了一个商店,并使用 Provider
组件提供了它。以极简的方式,商店设置如下:
const userSlice = createSlice({
name: 'user',
initialState: {
user: {}
},
reducers: {
validate: (state, action) => state.user = action.payload
}
})
const store configureStore({
reducer: {
user: userSlice.reducer
}
})
有两个组件 - 一个新的,功能性的,它使用 useSelector()
钩子,和一个旧的,它基于 class,但需要使用这个 sasme 商店来调度一个行动。
为此,我导入商店并启动
store.dispatch({type: 'user/validate', payload: newUser});
来自 class 组件。 我没有收到任何错误,但什么也没有发生。
我从 DevTools 的 Redux 插件跟踪了我的输入,我可以看到状态没有改变,所以我假设我对 dispatch
的手动调用有些错误。
我期望发生的是状态更新,这将触发使用 useSelector
以下方法是一种安全的分派操作的方法,不会拼错类型字符串。
- 从reducer中提取action
const userSlice = createSlice({
name: 'user',
initialState: {
user: {}
},
reducers: {
validate: (state, action) => {
state.user = action.payload
}
}
})
// <------------------
// Action creators are generated for each case reducer function
export const { validate } = userSlice.actions
export const store = configureStore({
reducer: {
user: userSlice.reducer
}
})
- 按原样发送操作
store.dispatch(validate(newUser))
问题
我要说的是,问题是您正试图在 reducer 函数 和 中同时改变状态对象 return它。
In any given case reducer, Immer expects that you will either mutate the existing state, or construct a new state value yourself and return it, but not both in the same function!
解决方案
只是改变状态,不要return它。
reducers: {
validate: (state, action) => {
state.user = action.payload;
},
}
如果您希望基于 class 的组件订阅您的 redux 存储,那么您仍然可以使用来自 react-redux
.
示例:
import { connect } from 'react-redux';
import { validate } from '../path/to/userSlice';
class MyComponent extends Component {
...
// In a function you can simply dispatch the validate action
// as it was wrapped in a call to dispatch already and injected
// as a prop.
this.props.validate(somePayloadValue);
...
}
const mapDispatchToProps = {
validate
};
export default connect(null, mapDispatchToProps)(MyComponent);