目录
2.1、componentWillReceiveProps(nextProps)
2.2、shouldComponentUpdate(nextProps,nextState)
2.4、componentDidUpdate(preProps,preState)
一、state(状态)
设置了state的组件称之为有状态组件
没有设置state的组件称之为无状态组件
1、读取状态
export class exer extends Component { state = { count: 0, } render() { return ( <div>{this.state.count}div> ) } }2、修改状态
this.setState({ 要修改的数据 })
注意:不能直接修改state中的值(例如:state:this.state.count = 1),必须通过setState方法进行修改
export class exer extends Component { state = { count: 0, } setcount = () => { this.setState({ count: this.state.count + 1, }) } render() { return ( <div> <p>{this.state.count}p> <button style={{ width: '50px', height: '20px', }} onClick={ this.setcount } > 按钮 button> div> ) } }3、setState注意点
在同步逻辑中,异步更新状态与真实dom
在异步逻辑中,同步更新状态与真实dom
接受第二个参数,是个回调函数,在这里状态与dom更新完成
二、属性props(只读)
1、数据传递
props是为了更好的实现复用性,从外部接受数据
//父组件 <MyNav title={this.title} /> //MyNav.js组件 render(){ return ( <div> <p>{this.props.title}<p/> div> ) }2、属性验证
import mypro from 'prop-types' static proTypes={ title: mypro.string, letBtn: mypro.bool }3、默认属性
static defaultProps={ title: '首页' }三、表单
1、受控表单组件
1.1、理解
input框自己的状态被React组件状态控制就是受控组件
1.2、实现步骤
2.1、在组件的state中声明组件的状态数据
2.2、将状态数据设置为input标签元素的value属性的值
2.3、为input添加change事件,通过事件对象e获取到当前文本框的值
2.4、调用setState方法,将文本框的值作为state状态的新值
export class exer extends Component { //组件状态数据 state = { mesg: 'msg', } //通过事件对象e获取当前文本框的值,并把文本框的值作为state状态的新值 getinput = (e) => { this.setState({ mesg: e.target.value, }) } render() { return ( <div> <input value={this.state.mesg} onChange={this.getinput}/> div> ) } }2、非受控表单组件
通过操作DOM获取文本框的值
在constructor中React.createRef()四、通信
1、父组件向子组件传递
使用属性值
1.1、步骤
1、父组件提供传递的数据
2、给子组件标签添加属性,值为state中的数据
3、子组件中通过props接收父组件中传过来的数据
1.2、实现
// 子组件 export class tab extends Component { render() { return ( <div> {this.props.msg} div> ) } } // 父组件 export class exer extends Component { state = { mesg: 'msg', } render() { return ( <div> <tab msg={this.state.mesg} /> div> ) } }2、子组件向父组件传递
使用回调函数
2.1、步骤
1、父组件提供一个回调函数,用于接收数据
2、将函数作为属性的值,传给子组件
3、子组件通过props调用回调函数
4、将子组件中的数据作为参数传给回调函数
2.2、实现
// 子组件 export class tab extends Component { render() { return ( <div> <p onClick={() =>{ this.props.changeMes("返回数据") } } >tabp> div> ) } } // 父组件 export class exer extends Component { state = { mesg: 'msg', } changemes = (newmsg) => { this.state({ meg: newmsg }) } render() { return ( <div> <tab changeMes={this.changemes} /> div> ) } }3、兄弟组件通信
由父组件充当中间人,利用子传父+父传子模式完成
1、公共父组件提供共享状态,提供共享状态的方法
2、要接收数据状态的子组件通过 props 接收数据
3、要传递数据状态的子组件通过props接收方法,调用方法传递数据
4、发布订阅模式
let bus = { list:[], //存放订阅者 //订阅者 subscrible(cb){ this.list.push(cb); }, //发布者 publish(text){ this.list.forEach(cb => cb && cb(text)) } }5、context状态树传参(官方提供)
Context提供了一个无需为每层组件手动添加props,就能在组件树间进行数据传递的方法
步骤
1、创建Context对象
const GlobalContext = React.createContext()
2、使用GlobalContext.Provider包裹上层组件提供数据
<GlobalContext.Provider value = {{a:1,b:2}}> <p>p> <p>p> GlobalContext.Provider>3、需要用到数据的组件使用GlobalContext.Consumer包裹获取数据
<GlobalContext.Consumer> { value =>{ return ( <div>子组件{value}div> ) } } GlobalContext.Consumer>五、生命周期(钩子函数)
1、初始化阶段
1.1、componentWillMount
组件即将挂载,render之前最后一次修改state的机会
常用于:state的初始化
备注:如果有警告,可使用UNSAFE_componentWillMount
1.2、render
只能访问props与state,不能修改state及进行dom输出
1.3、componentDidMount
成功执行完毕render并完成dom节点的渲染,可以对dom修改
常用于:axios请求,订阅函数调用,计时器,dom操作
2、运行中阶段
2.1、componentWillReceiveProps(nextProps)
父组件修改属性触发
最先获取父组件传来的属性,可以在这里进行axios请求或者其他逻辑处理
备注:如果有警告,可使用UNSAFE_componentWillReceiveProps
2.2、shouldComponentUpdate(nextProps,nextState)
返回false,会阻止render的调用
参数是被修改之后的新的属性及状态
2.3、render
只能访问props与state,不能修改state及进行dom输出
2.4、componentDidUpdate(preProps,preState)
可以修改dom
参数是被修改之前的属性及状态
3、销毁阶段
componentWillUnmount
在删除组件前进行清理工作