问题如下:
我有几千个元素列表形式的数据。其中一些是重复的,然后也可能有重复的键。因为我没有真正的“ID”或任何可以让我有机会将所有元素的 id 作为唯一键的东西,所以可以Math.random()
改用吗?
据我了解,key主要是react用来区分组件的。我认为就我的代码中的键而言,我真的没有任何关系,这应该没问题吗?为了确保不会有重复的数字,我不妨将两个数学随机数相互除以得到一个几乎可以肯定的唯一键。
这是一个好习惯吗?我可以使用它而不必担心任何事情吗?
问题如下:
我有几千个元素列表形式的数据。其中一些是重复的,然后也可能有重复的键。因为我没有真正的“ID”或任何可以让我有机会将所有元素的 id 作为唯一键的东西,所以可以Math.random()
改用吗?
据我了解,key主要是react用来区分组件的。我认为就我的代码中的键而言,我真的没有任何关系,这应该没问题吗?为了确保不会有重复的数字,我不妨将两个数学随机数相互除以得到一个几乎可以肯定的唯一键。
这是一个好习惯吗?我可以使用它而不必担心任何事情吗?
每次组件的键更改时,React 都会创建一个新的组件实例而不是更新当前的组件实例,因此出于性能考虑,使用 Math.random() 至少可以说是次优的。
此外,如果您要以任何方式重新排列组件列表,使用索引作为键也无济于事,因为 React 协调器将无法移动与组件关联的现有 DOM 节点,而是必须重新-为每个列表项创建 DOM 节点,这将再次具有次优性能。
但重申一下,这只会在您对列表重新排序时出现问题,因此在您的情况下,如果您确定不会以任何方式对列表重新排序,则可以安全地使用索引作为键。
但是,如果您确实打算重新排序列表(或只是为了安全),那么我将为您的实体生成唯一 ID - 如果您没有可以使用的预先存在的唯一标识符。
添加 id 的一种快速方法是在您第一次接收(或创建) list 时映射列表并为每个项目分配索引。
const myItemsWithIds = myItems.map((item, index) => { ...item, myId: index });
这样每个项目都会获得一个唯一的静态 ID。
tl;dr 如何为找到此答案的新人选择一把钥匙
如果您的列表项具有唯一 id(或其他唯一属性),请将其用作键
如果您可以组合列表项中的属性以创建唯一值,请使用该组合作为键
如果上述方法均无效,但您可以保证不会以任何方式对列表重新排序,则可以使用数组索引作为键,但最好将自己的 id 添加到列表项中首先收到或创建(见上文)
只需在您的react组件中实现以下代码...
constructor( props ) {
super( props );
this.keyCount = 0;
this.getKey = this.getKey.bind(this);
}
getKey(){
return this.keyCount++;
}
...并在this.getKey()
每次需要新密钥时调用,例如:
key={this.getKey()}
从react文档:
密钥应该是稳定的、可预测的和唯一的。不稳定的键(如 Math.random() 生成的键)将导致不必要地重新创建许多组件实例和 DOM 节点,这可能导致子组件的性能下降和状态丢失。
密钥应该是稳定的、可预测的和唯一的。不稳定的键(如 Math.random() 生成的键)将导致不必要地重新创建许多组件实例和 DOM 节点,这可能导致子组件的性能下降和状态丢失。
这是一个好习惯吗?我可以使用它而不必担心任何事情吗?
没有也没有。
密钥应该是稳定的、可预测的和唯一的。不稳定的键(如 Math.random() 生成的键)将导致不必要地重新创建许多组件实例和 DOM 节点,这可能导致子组件的性能下降和状态丢失。
让我用一个简单的例子来说明这一点。
class Input extends React.Component {
handleChange = (e) => this.props.onChange({
value: e.target.value,
index: this.props.index
});
render() {
return (
<input value={this.props.value} onChange={this.handleChange}/>
)
}
};
class TextInputs extends React.Component {
state = {
textArray: ['hi,','My','Name','is']
};
handleChange = ({value, index}) => {
const {textArray} = this.state;
textArray[index] = value;
this.setState({textArray})
};
render(){
return this.state.textArray.map((txt, i) => <Input onChange={this.handleChange} index={i} value={txt} key={Math.random()}/>)
// using array's index is not as worse but this will also cause bugs.
// return this.state.textArray.map((txt, i) => <Input onChange={this.handleChange} index={i} value={txt} key={i}/>)
};
};
为什么我不能在你问的输入中输入一个以上的字符?
这是因为我使用 Math.random() 作为关键props映射多个文本输入。每次我输入一个字符时,onChange props都会触发,并且父组件的状态会发生变化,这会导致重新渲染。这意味着每次输入都会再次调用 Math.random 并生成新的关键props。因此,react 会呈现新的子项 Input 组件。换句话说,每次键入一个字符时,react 都会创建一个新的输入元素,因为关键props发生了变化。
在此处阅读更多相关信息