你能把切片放在里面吗?如何在切片之间共享状态逻辑



EDIT:为了获得完整的参考,我试图用Redux 来做这件事

https://codesandbox.io/s/github/SenBoyer/codm-tracker-unfinished

快速视觉参考:

https://jsfiddle.net/59r31Lmt/

我试着让它在你点击一个迷彩方块时变成活动的,当你点击所有迷彩方块,金色解锁,当你解锁所有枪支的金色时,钻石";解锁"/变得对所有人都很活跃。

这是我正在使用的切片

import { createSlice } from "@reduxjs/toolkit";
const initialState = {
sandIsActive: false,
jungleIsActive: false,
splinterIsActive: false,
tigerIsActive: false,
dragonIsActive: false,
reptileIsActive: false,
goldIsActive: false,
diamondIsActive: false,
};
const camoBarSlice = createSlice({
name: "camoBar",
initialState,
reducers: {
setSandActive: (state, action) => {
return {
...state,
sandIsActive: !state.isActive,
};
},
setJungleActive: (state, action) => {
return {
...state,
jungleIsActive: !state.isActive,
};
},
setSplinterActive: (state, action) => {
return {
...state,
splinterIsActive: !state.isActive,
};
},
setTigerActive: (state, action) => {
return {
...state,
tigerIsActive: !state.isActive,
};
},
setDragonActive: (state, action) => {
return {
...state,
dragonIsActive: !state.isActive,
};
},
setReptileActive: (state, action) => {
return {
...state,
reptileIsActive: !state.isActive,
};
},
setGoldActive: (state, action) => {
return {
...state,
goldIsActive: !state.isActive,
};
},
},
});

所以当

sandIsActive: true,
jungleIsActive: true,
splinterIsActive: true,
tigerIsActive: true,
dragonIsActive: true,
reptileIsActive: true,

setGoldActive((运行并:

goldIsActive: true

然后,当goldIsActive对所有20支枪都为true时,setDiamondActive((运行并:

diamondIsActive: true

每支枪。

我如何在所有枪之间共享状态逻辑,以便在它们都变为活动时知道运行函数setDiamondActive?

我必须用相同的逻辑为每把枪制作一个单独的切片吗?然后呢?如何传递逻辑?

我是否必须为整个网站上的每个正方形添加一个状态值,因为不可能在其他切片之间共享状态值?你需要把它都放在一片里吗?所以它必须是这样的:

const initialState = {
ak47SandIsActive: false,
ak47JungleIsActive: false,
ak47SplinterIsActive: false,
ak47TigerIsActive: false,
ak47DragonIsActive: false,
ak47ReptileIsActive: false,
ak47GoldIsActive: false,
ak47DiamondIsActive: false,
m13SandIsActive: false,
m13JungleIsActive: false,
m13SplinterIsActive: false,
m13TigerIsActive: false,
m13DragonIsActive: false,
m13ReptileIsActive: false,
m13GoldIsActive: false,
m13DiamondIsActive: false,
};

然后在每个方块上设置一个onClick,并执行相关的调度操作?

我可以把一片放在另一片里面吗?这样我就可以有一个";外减速器";控制菱形方块,而内部减速器控制整个枪逻辑?有什么接近或可以完成同样的事情吗?

基本上,我如何使用redux来跟踪这里的状态?我发布的切片中的逻辑一次只适用于一支枪,但我如何使用它来控制这里20多支枪的逻辑?

我将对您的代码做一些假设:

  • 您想知道每个枪何时处于活动状态
  • 您想知道某些枪支何时处于活动/非活动状态
  • 这些枪支的状态之间有着复杂的相互作用

为此,我的建议是将所有内容合并到一个切片中。如果您需要访问另一个切片中的一个切片的数据,那么,实际上,这是一个切片,因为范围是相同的。将切片视为范围。

首先,我们需要一个函数来确定diamond何时应该打开:

export const isDiamondActive = (state) => {
const targetKeys = ['sand', 'jungle', reptile'...];

targetKeys.forEach(targetKey => {
if(state[targetKey] === false) {
return false;
}
}
return true;
}

这个函数简单地循环所有的键,如果它们都是true,则应该告诉我们diamond也应该是活动的。记住这个功能。

此外,使用RTK,您不再需要担心复制";过去状态";就像你对Redux所做的那样。只要写下你的逻辑,不要去想,所以:

setReptileActive: (state, action) => {
return {
...state,
reptileIsActive: !state.isActive,
};
},

变为:

setReptileActive: (state, action) => {
state[reptileIsActive] = !state[reptileIsActive];
},

或者,更好的是,删除上面所有的reducer,并在一个函数中重构它:

toggledGunStatus: (state, action) => {
const { id } = action;

//If the did we were provided isn't in the state, stop.
if(!(id in state)) {
return;
}
state[id] = !state[id];
}

考虑到所有这些,我们有两个选择。我认为isDiamondActive的检查应该在toggleGunStatus减速器内部进行,因为它们紧密地联系在一起。所以,一个简单的:

const diamondActive = isDiamondActive(state);
if(diamondActive) {
state['diamond'] = diamondActive;
}

然而,当我们谈论复杂逻辑时,事情可能会变得一团糟,因此,也许您希望为此设置一个侦听器中间件——它只需侦听toggledGunStatus操作,并作为响应,进一步运行isDiamondActive检查和调度/更改状态。


顺便说一句,我觉得你的系统会更复杂一些。每把枪都会保存大量数据,而不仅仅是isActive标志。考虑一下实体适配器,它为项目集合提供了预构建的CRUD操作。从本质上讲,切片应该是一组对象,其中每个对象都是一把枪。如果你使用的是TS,你可以优雅地将所有这些定义为:

export type Gun = {
id: string;
isActive: boolean;
}
export const entityAdapter = createEntityAdapter<Gun>();
..
const initialState: InitialState /* complex, can ignore */ = {
guns: entityAdapter.getInitialState();
}

现在,每当你使用选择器时,你都在使用一个集合。更干净;未来证明";。

相关内容

  • 没有找到相关文章

最新更新