21.什么是 “key” 属性,在元素数组中使用它们有什么好处?
key
是一个特殊的字符串属性,你在创建元素数组时需要包含它。Keys 帮助 React 识别哪些项已更改、添加或删除。
我们通常使用数据中的 IDs 作为 keys:
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
)
在渲染列表项时,如果你没有稳定的 IDs,你可能会使用 index 作为 key:
const todoItems = todos.map((todo, index) =>
<li key={index}>
{todo.text}
</li>
)
注意:
- 由于列表项的顺序可能发生改变,因此并不推荐使用 indexes 作为 keys。这可能会对性能产生负面影响,并可能导致组件状态出现问题。
- 如果将列表项提取为单独的组件,则在列表组件上应用 keys 而不是
li
标签。 - 如果在列表项中没有设置
key
属性,在控制台会显示警告消息。
22.refs 有什么用?
ref 用于返回对元素的引用。但在大多数情况下,应该避免使用它们。当你需要直接访问 DOM 元素或组件的实例时,它们可能非常有用。
23.如何创建 refs?
这里有两种方案
- 这是最近增加的一种方案。Refs 是使用
React.createRef()
方法创建的,并通过ref
属性添加到 React 元素上。为了在整个组件中使用refs,只需将 ref 分配给构造函数中的实例属性。
class MyComponent extends React.Component {
constructor(props) {
super(props)
this.myRef = React.createRef()
}
render() {
return <div ref={this.myRef} />
}
}
- 你也可以使用 ref 回调函数的方案,而不用考虑 React 版本。例如,访问搜索栏组件中的
input
元素如下:
class SearchBar extends Component {
constructor(props) {
super(props);
this.txtSearch = null;
this.state = { term: '' };
this.setInputSearchRef = e => {
this.txtSearch = e;
}
}
onInputChange(event) {
this.setState({ term: this.txtSearch.value });
}
render() {
return (
<input
value={this.state.term}
onChange={this.onInputChange.bind(this)}
ref={this.setInputSearchRef} />
);
}
}
注意: 你也可以使用内联引用回调,尽管这不是推荐的方法。
24.为什么不建议使用内联引用回调或函数?
如果将 ref 回调定义为内联函数,则在更新期间它将会被调用两次。首先使用 null 值,然后再使用 DOM 元素。这是因为每次渲染的时候都会创建一个新的函数实例,因此 React 必须清除旧的 ref 并设置新的 ref。
class UserFor