- 组件中不想在真实DOM中渲染出多余的父元素标签
import {Fragment} from 'react'
render () {
return (
<Fragment>
<div>hello</div>
<div>world</div>
</Fragment>
)
}
渲染结果:
- setState方法中不要直接操作state
//不好的写法
this.setState({
list: this.state.list.push(1)
})
//正确的写法
const list = [...this.state.list]
list.push(1)
this.setState({
list
})
- 标签内容不转义渲染–
dangerouslySetInnnerHTML
<li>{item}</li>
//当item="<h1>hello world</h1>"时,显示'<h1>hello world</h1>'
<li dangerouslySetInnerHTML={{__html:item}}></li>
//此时不会item的内容不会被转义,正确显示'hello world',大小为h1的大小
- propTypes和defaultProps
TodoItem.propTypes {
test: PropTypes.String.isRequest // String类型、必需
}
TodoItem.defaultProps {
test: 'hello' //默认值
}
详情可看官网
- prop或state改变(实际上prop改变也是由于state改变),render()都会重新执行
- 虚拟DOM
- state 数据
- JSX 模板
- 数据 + 模板 结合 生成虚拟DOM
['div', {id: 'abc'}, ['span', {}, 'hello world']]
- 用虚拟DOM的结构生成真实DOM,来显示。
- state 发生改变
- 数据 + 模板 生成新的虚拟DOM(极大提升了性能)
['div', {id: 'abc'}, ['span', {}, 'bye, bye']]
- 比较原始虚拟DOM的新的虚拟DOM的区别,找到区别是span中内容(极大提升了性能)
- 直接操作DOM,改变span中的内容
- JSX -> React.createElement() -> 虚拟DOM(js对象) -> 真实DOM
- react 16版本将
setState()
变成异步方法
this.setState((prevState) => {
const list = prevState.list
list.push(4)
return {list}
}, () => {console.log(this.state.list)}) //回调函数
改成异步方法是为了在一定时间内累积state变动,得到最后对比完成的虚拟DOM,再一次性的操作真实DOM,避免短时间内多次操作虚拟DOM和真实DOM,浪费性能。
- diff算法
- key值不要用index, 提高diff算法的性能
11.react组件生命周期函数 – 某个时刻组件会自动调用执行的函数
// 组件更新之前会自动执行,需要返回Boolean
shouldComponentUpdate(){}
// 组件被更新之前,它会自动执行,但是在shouldComponentUpdate()之后执行
// 如果shouldComponentUpdate返回true它才会执行
// 如果shouldComponentUpdate返回false,它不会执行
componentWillUpdate(){}
/* componentWillReceiveProps触发条件
* 一个组件要从父组件接受prop参数
* 如果这个组件第一次存在于父组件中,不会执行
* 如果这个组件之前已经存在于父组件中,才会执行
*/
componentWillReceiveProps(){}
- redux
redux = reducer + flux(早期Facebook使用的框架,已过时)
注意: 当store改变之后,需要重新获取store中最新的state
store.subscribe(this.handleStoreChange.bind(this)) // store有改动就会触发这个函数
this.handleStoreChange() {
this.setState(store.getState()) // 重新获取最新的state
}