如何控制使用Redux
动态添加的组件的状态?当使用React
控制状态时,我能够做到这一点,但当我引入Redux
时,每个组件都具有相同的状态。
在下面的示例中,单击按钮以添加父项。然后单击按钮添加新的子项。再次单击“添加新父级”按钮时,第二个父级与第一个父级具有相同的子级数。是否可以单独管理每个父状态,知道可以有任意数量的父状态,或者我应该坚持使用React
控制状态?
下一步是使用每个父节点的print child info按钮打印所有子节点中的文本,但由于子节点的状态与父节点的控制方式类似,我认为一旦我克服了第一个障碍,这将很容易。
下面是目录结构和代码:
├── src
│ ├── App.jsx
│ ├── appSlice.js
│ ├── components
│ │ ├── Child.jsx
│ │ ├── Parent.jsx
│ │ ├── childSlice.js
│ │ └── parentSlice.js
│ ├── main.jsx
│ └── store
│ └── store.js
main.jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { Provider } from "react-redux";
import App from './App'
import { store } from "./store/store";
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
)
App.jsx
import { useDispatch, useSelector } from "react-redux"
import { addParent } from "./appSlice"
import Parent from "./components/Parent";
export default function App() {
const dispatch = useDispatch();
const {parents} = useSelector(state => state.app)
return (
<div style={{
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
margin: '2rem'
}}>
<button onClick={() => dispatch(addParent())}>Add parent</button>
<br />
{parents.map((item) => (
<Parent key={item}/>
))}
</div>
)
}
appSlice.js
import { v4 as uuid} from "uuid"
import { createSlice } from "@reduxjs/toolkit";
const appSlice = createSlice({
name: "app",
initialState: {
parents: []
},
reducers: {
addParent: (state) => {
state.parents = [...state.parents, uuid()];
},
},
});
export const { addParent } = appSlice.actions;
export default appSlice.reducer;
store/store。js
import { configureStore } from "@reduxjs/toolkit";
import appReducer from "../appSlice";
import parentReducer from "../components/parentSlice";
import childReducer from "../components/childSlice"
export const store = configureStore({
reducer: {
app: appReducer,
parent: parentReducer,
child: childReducer
},
});
**components/Parent。联系我们
import React from 'react'
import Child from './Child'
import { useDispatch, useSelector } from "react-redux"
import { addChild } from "./parentSlice"
export default function Parent() {
const dispatch = useDispatch()
const {children} = useSelector(state => state.parent)
return (
<div style={{
width: "100%",
height: "100px",
border: "1px solid black",
marginBottom: "10px",
}}>
<button onClick={() => dispatch(addChild())}>Add new child</button>
{children.map(item => (
<Child key={item} />
))}
<button>Print child info</button>
</div>
)
}
components/parentSlice。js
import { v4 as uuid} from "uuid"
import { createSlice } from "@reduxjs/toolkit";
const parentSlice = createSlice({
name: "parent",
initialState: {
children: []
},
reducers: {
addChild: (state) => {
state.children = [...state.children, uuid()];
},
},
});
export const { addChild } = parentSlice.actions;
export default parentSlice.reducer;
**components/Child。联系我们
import React from 'react'
import { useDispatch } from 'react-redux'
import { updateText } from './childSlice';
export default function Child() {
const dispatch = useDispatch();
return (
<div>
<input
type='text'
onChange={(event) => dispatch(updateText(event.target.value))}
></input>
</div>
)
}
components/childSlice。js
import { createSlice } from "@reduxjs/toolkit";
const childSlice = createSlice({
name: "child",
initialState: {
text: "",
},
reducers: {
updateText: (state, {payload}) => {
state.text = payload;
},
},
});
export const { updateText } = childSlice.actions;
export default childSlice.reducer;
1条答案
按热度按时间laik7k3q1#
在React中,UI是state和props的函数。在这种情况下,状态是您的Redux商店。基本上,代码中缺少的是子id值与 some 父id值的关联。所有的子节点都使用相同的
state.child
状态值,没有任何区别。我建议进行以下状态切片更改:
更新状态
appSlice
-这里没有什么变化,仍然是父“节点”id的数组。parentSlice
-在这里,您希望状态是一个对象,其中生成的父ID是键,值是子ID值的数组。childSlice
-类似地,子状态将是一个对象,其中键是子id值,值是输入值。从State渲染UI
App
-选择state.app.parents
(* 或Object.keys(state.parent)
!* )并将此数组Map到Parent
组件,并将id作为prop传递。Parent
-类似地,获取传递的id
属性并选择state.parent.children[id]
以获得***this***parent的children id值数组。将它们Map到Children
组件,并再次将子组件的id值作为prop传递。Parent
将把它的id
值传递给分派的addChild
动作,这样reducer就知道要向哪个父对象添加子对象。Child
-子组件将使用传递的id
prop 通过state.child[id]
选择其值,并呈现其输入。Child
将其id
值***和***输入值传递给分派的updateText
action,这样reducer函数就知道哪个子ID正在更新。Demo