State
state 状态,是 Component 的属性,我们会将组件相关的数据放入 state ,然后通过 state 属性 和 组件要构建的视图进行绑定,当 state 更新时,同步会更新我们的视图
- setState(updater, [callback])
- updater: 更新数据 FUNCTION/OBJECT
- callback: 更新成功后的回调 FUNCTION
- 异步:react通常会集齐一批需要更新的组件,然后一次性更新来保证渲染的性能
- 浅合并 Objecr.assign()
- 调用 setState 之后,会触发生命周期,重新渲染组件
state的浅合并
// 注意一下浅合并 =》 state 只会进行一层的浅合并,如果state超过一层
state={
data:{
name:'pika',
count:1
}
}
// 在调用的时候,我们需要把数据手动合并
this.setState({
data:{
...this.state.data,
count:count + 1
}
})
state的异步更新
react 通常会集齐一批需要更新的组件,然后一次性更新来保证渲染的性能。也就是说,你在JSX中多次调用setState方法,他不会利用通过render渲染出来,而是在完成更新之后,再到render中一次性渲染。
props
props 接收父组件传递过来的数据
- props 是父组件传递过来的信息,在组件内部不能直接修改 props
父传子
子传父
在父组件中定义回调函数,子组件通过props获取回调函数,并且把参数传进去,从而改变父组件的state
兄弟传
先通过子传父,然后父传子,完成通讯
对象怎么转化成数组— 组件通信(好友列表)
object.key()
// 数据格式 =》 {{},{},{}}
let datas = {
family: {
title: '家人',
list: [
{name: '爸爸'},
{name: '妈妈'}
]
},
friend: {
title: '朋友',
list: [
{name: '张三'},
{name: '李四'},
{name: '王五'}
]
},
customer: {
title: '客户',
list: [
{name: '阿里'},
{name: '腾讯'},
{name: '头条'}
]
}
};
object.keys(datas).map((item,index)=>{
console.log(datas[item])
})
// 最终获得
[
{
title:''
list:[]
},{
title:''
list:[]
},{
title:''
list:[]
},
]
注意:JSX在内容插值的时候,只能插入数字,字符串以及数组
生命周期
副作用:异步、DOM 操作
副作用:操作一般放在 componentDidMount 和 componentDidUpdate 中
key 的问题
在 React ,组件每次更新时,会生成一个 虚拟DOM,和原有的虚拟DOM进行对比。
如果是批量生成的一组元素,那React就会根据 key 值去做对比
一个列表中的每一项 key 是唯一的
如果列表中发生顺序等操作变化,key 一定要用数据的id
**
key 该如何取值?
两个原则:
1. 一个列表中的每一项 key 是唯一的
2. 视图更新前后,同一个元素的 key 值,要保持不变
1. 如果数据的顺序会发生变化 key 最好使用 数据的id
2. 如果明确知道 key 顺序不会变化,用 index 也无所谓
PureComponent
PureComponent 提供了一个具有浅比较的 shouldComponentUpdate 方法,其他和 Component 完全一直
// PureComponent提供的只是浅对比,所以在引用的时候需要每次都返回一个新的引用
this.setState({
data:[...data]
})
ref 获取DOM
在编辑组件的时候,需要获取组件的DOM进行状态的改变
其中涉及
current.focus()
onBlur()
onDoubleClick()
编辑功能: !!! 当用户清空输入框的信息后,还保持原来的信息,否则信息和用户输入数据保持一致
1. 将数据复制一份 state.val = props.data.value
2. 失去焦点时
判断输入框是否为空,
为空
将 state.val 恢复为 props.data.value
否则
props.data.value = state.val
使用constructor的时机
每次初始化的时候只执行一次,所以用constructor进行数据拷贝
如果用常规的state,只能在render里面获取props
使用ref三步走
// 1.先创建一个ref对象
helloRef = createRef()
// 2.将对象添加到需要获取DOM的元素的ref属性上
<div ref ={this.helloRef}>hello</div>
// 3.在组件完成挂载的时候,通过this.helloRef.current()拿到元素DOM节点
componentDidMount(){
console.log(this.helloRef.current)
}