下午好,星期五快乐,
我最近开始学习如何使用Redux作为管理我的应用程序中的状态的方法,到目前为止我喜欢它,但是我无法动态地将道具分配给父组件的子项。
以下是我正在使用的内容,有孩子的基本父母情景:
<Layout>
<Child />
<Child />
<Child />
</Layout>
我希望每个孩子都有一个唯一身份证明,因此第一个孩子的childProps.id
为1
,第二个孩子为2
,依此类推。
这里首先是我想在渲染组件时触发的assignId
函数:
export function assignId(number){
return{
type: "ASSIGN",
payload: number
}
}
以下是监听此功能的reducer:
export default function reducer(state={
id: 0
}, action){
switch (action.type){
case "ASSIGN": {
return {...state, id: action.payload}
}
}
return state
}
最后是<Child />
组件本身:
import React from "react";
import { activeBox, beginSession, unselect, assignId } from '../actions/boxActions'
export default class Child extends React.Component {
componentWillMount(){
var i = 1
this.props.dispatch(assignId(i));
i++
}
render(){
return (
<div className="box"></div>
)
}
}
componentWillMount
有效。我var i = 1
为我childProps.id
组件的所有设置<Child />
为1。简单地说,我如何根据childProps.id
父级中的顺序创建一个使每个<Child />
组件的每个<Layout />
唯一的函数?任何和所有的帮助表示赞赏。
周末愉快
答案 0 :(得分:5)
我认为你在零价值方面增加了复杂性。 DOM元素的id
属性肯定是唯一的,因此您处于正确的轨道上,但是
Child
个组件并从可迭代中反映出来,为什么不使用Array#map
?所以
render() {
const childElements = [1, 2, 3];
return (
<Layout>
<Child id="1" />
<Child id="2" />
<Child id="3" />
</Layout>
);
}
变成
render() {
const childElements = [1, 2, 3];
return (
<Layout>
{childElements.map((id, index) => (
<Child
key={index}
id={id} />
))}
</Layout>
);
}
从您的代码中,我可以看到您想要分配一个操作来分配带有ID的元素,而该ID甚至不存储在任何地方。如果它确实没有被存储和用于任何目的,则不需要它。
React的一般规则是简单而不复杂。您拥有数据,您可以使用组件(以及它们形成的层次结构)将这些数据反映到DOM中,以及它。如果您需要收听DOM事件,请使用onClick
,onChange
和其他props that are bound to DOM event listeners,以及它。一旦你想使用一个与DOM一起使用的lib,试着坚持使用ref而不是id
s,因为那些保证引用现有的DOM元素,id
引用可能导致无处可去正在更新组件。
答案 1 :(得分:5)
与其他人所说的相反,将ID分配给商店中的数组项是很有意义的。渲染它们时,您可以将此ID作为key
道具传递给每个子组件。当您插入,删除或重新排序数组项时,这开始很有意义。 React将使用此键来帮助它找到与数组项匹配的正确组件。当商店项目索引发生变化时,这可以加速渲染。
这就是key
道具存在的原因,也是你不应该简单地使用项目索引的原因。索引与身份不同。
现在,要生成并存储这样一个唯一ID,请执行以下操作:
let nextId = 0;
function addItem(item) {
return {
type: 'ADD_ITEM',
payload: {
...item,
id: nextId++
}
};
}
function reducer(state = [], action) {
switch action.type {
case 'ADD_ITEM':
return [...state, action.payload]
break;
default:
return state;
}
}
然后,您可以将此ID分配给每个孩子的关键支柱。它对于会话来说是独一无二的,而且您可能需要它。如果没有,您可以生成您喜欢的任何其他ID,例如GUID。在任何情况下,重要的是您希望ID从一开始就是项目的一部分,并且ID不是也不应该分配给组件,而是分配给组件将要显示的项目。该组件假定商店中找到的商品的标识,而不是相反。
答案 2 :(得分:1)
在父级别,将您的孩子ID放在数组中,循环播放,并将id指定为孩子的道具。
像这样的东西
<Layout>
{childrenIds.map((i) => { return <Child id={i} />} )}
</Layout>
我希望有帮助