如何使用 redux-toolkit 访问 redux 中另一个切片的状态?

Jer*_*ias 37 reactjs redux react-redux redux-toolkit

在我的 Redux 存储中,我有多个切片,我想访问langspeciesSlice 内的settingsSlice 的状态。

这是我的切片的代码示例:

const settingsSlice = createSlice({
  name: 'settings',
  initialState: { lang: 'en', theme: 'dark' },
  reducers: {
    ...
  },
});

const speciesSlice = createSlice({
  name: 'species',
  initialState: data[`vds-list-${HERE I WANT TO USE THE "lang" STATE OF THE SETTINGSSLICE}`],
  reducers: {
    ...
  },
});
Run Code Online (Sandbox Code Playgroud)

到目前为止我还没有找到解决方案,所以也许这是不可能的?

我可以只使用一个切片,其中包含所有状态,但我真的很想将状态的不同部分分隔在不同的切片中。

mar*_*son 26

根据定义,Reducer 只能访问它们拥有的状态部分。因此,如果我有{users: usersReducer, posts: postsReducer},则根本usersReducer无法访问状态切片。posts

请参阅Redux 常见问题解答条目“如何在减速器之间共享状态?” 更多细节。


Bis*_*mad 11

我已经通过简单地导入 redux 存储对象并调用getState()方法来实现这一点。

所以在speciesSlice减速器动作中你可以这样做:

const speciesSlice = createSlice({
  name: 'species',
  initialState: data[`vds-list-${HERE I WANT TO USE THE "lang" STATE OF THE SETTINGSSLICE}`],
  reducers: {
    ...
    setLang: (state, _) => {
      const reduxStore = store.getState();
      const lang = reduxStore.settingsSlice.lang;
      state = data[`vds-list-${lang}`];
    },
    ...
  },
});
Run Code Online (Sandbox Code Playgroud)

  • 这会被认为是不好的做法/反模式吗? (9认同)
  • @Dror 就我个人而言,我认为这是一种需要避免的反模式。看起来这个示例中的减速器实际上并没有做任何事情,并且可以轻松地用选择器替换(选择器选择活动语言并返回相应的数据)。 (4认同)

小智 6

我们可以通过添加extraReducers响应来做到这一点action

// Slice A - sliceA.js
export const sliceAinitialState = {
  lang: 'en',
}
const sliceA = createSlice({
  name: 'A'
  initialSlice: sliceAinitialState,
  reducers: {
    langChangedAtSliceA: (state, action) => state.lang = action.payload,
  }
})
export const {langChangedAtSliceA } = sliceA.actions

// Slice B - sliceB.js
import {sliceAinitialState, langChangedAtSliceA} from 'sliceA.js'
const sliceB = createSlice({
  name: 'B'
  initialSlice: {
    lang: sliceAinitialState.lang
  },
  extraReducers: (builder) => {
    builder.addCase(langChangedAtSliceA, (state, action) => {
      state.lang = action.payload
    })
  }
})
Run Code Online (Sandbox Code Playgroud)