React - 父子传值与循环key
# 父传值给子组件
父组件调用子组件的标签时,后面直接加 key=value
。
如 Item 标签传入了 key={todo.id} {...todo}
render() {
const {todos,updateTodo,deleteTodo} = this.props
return (
<ul className="todo-main">
{
todos.map( todo =>{
return <Item key={todo.id} {...todo}/>
})
}
</ul>
)
}
2
3
4
5
6
7
8
9
10
11
12
# 子传值给父组件
父组件事先写好一个(带有参数)函数,然后作为属性传入子组件,子组件只需要调用该函数并传入参数即可,实际就是子组件帮父组件调用自己的函数。
// 父组件
render() {
const {todos} = this.state
return (
<div className="todo-container">
<div className="todo-wrap">
<Header addTodo={this.addTodo}/>
<List todos={todos} updateTodo={this.updateTodo} deleteTodo={this.deleteTodo}/>
<Footer todos={todos} checkAllTodo={this.checkAllTodo} clearAllDone={this.clearAllDone}/>
</div>
</div>
)
}
// 子组件 Header
// 定义一个函数
updateTodo = () => {
const { updateTodo, deleteTodo} = this.props;
// 调用父组件传来的函数,把值传给父组件
updateTodo("我是子组件");
deleteTodo("我是子组件");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 循环 key
循环的 key 不建议使用 index。
经典面试题:
react/vue 中的 key 有什么作用?(key 的内部原理是什么?)
为什么遍历列表时,key 最好不要用 index?
虚拟 DOM 中 key 的作用
简单的说: key 是虚拟 DOM 对象的标识,在更新显示时 key 起着极其重要的作用。
详细的说: 当状态中的数据发生变化时,React 会根据【新数据】生成【新的虚拟 DOM】,随后 React 进行【新虚拟 DOM】与【旧虚拟 DOM】的 diff 比较,比较规则如下:
- 旧虚拟 DOM 中找到了与新虚拟 DOM 相同的 key:
- 若虚拟 DOM 中内容没变,直接使用之前的真实 DOM
- 若虚拟 DOM 中内容变了,则生成新的真实 DOM,随后替换掉页面中之前的真实 DOM
- 旧虚拟 DOM 中未找到与新虚拟 DOM 相同的 key:
- 根据数据创建新的真实 DOM,随后渲染到到页面
用 index 作为 key 可能会引发的问题
若对数据进行逆序添加、逆序删除等破坏顺序操作:
- 会产生没有必要的真实 DOM 更新,导致界面效果没问题,但效率低
如果结构中还包含输入类的 DOM:
- 会产生错误 DOM 更新,界面有问题
注意:如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用 index 作为 key 是没有问题的。
开发中如何选择 key
最好使用每条数据的唯一标识作为 key,比如 id、手机号、身份证号、学号等唯一值。
如果确定只是简单的展示数据,用 index 也是可以的。
# this问题
将 this 指向类的实例。
在 class 类里,除了自带的函数(constructor、render....),其他自定义函数需要调用都必须由该类实例调用,所以 this 需要指向该类的实例,即可使用 this.xxx
方法
this 在函数的作用域是指向函数,而不是类的实例,故无法调用类的其他函数。
如果需要在函数里调用其他方法,则需要使用 箭头函数,把 this 指向类的实例,即可
this.
其他方法。即需要使用函数名 = () => {}
赋值法,因为箭头函数没有名字,只能赋值给一个变量,通过变量调用该函数。使用
bind(this)
,在 constructor 或者 render 里,把 this 传给方法,可以改变方法的 this。 原理:xxx.bind()
方法是创建出一个新的函数,该函数和 xxx 的功能一模一样,xxx.bind(this)
创建新的和 xxx 一样的函数,同时把 this(React的) 传进来替换原来的 this(函数的)- 如果在类自带的函数里使用
xxx.bind(this)
,则该 this 就是指向类的实例,从而替换内部函数的 this,实现可以调用类的方法
建议(流行) 使用箭头函数
export default class Form extends Component {
// 错误
function1(){
// this 是函数的 this,没有 React 的数据 state 等
}
// 正确
funtion2 = () => {
// this 是 React 的函数,可以调用其他 React 的函数和 s 数据
}
}
2
3
4
5
6
7
8
9
10