组件状态
事件
(事件名大写)
注意:组件事件需要配合状态,所以现在无法呈现效果
class Cmp1 extends React.Component{
constructor(...args){
super(..args);
this.a=0;//要用状态,属性不行,props也不行
}
add(){
this.a++;
//这个函数会执行,a也会变,但是不会重新渲染
alert(this.a);
}
render(){
return <div>
//强制绑定add的this
<input type="button" value="加1" onClick={this.add.bind(this)} />
</div>
}
}
复制代码
a其实变了,但是只有状态改变能引发重新渲染
状态
组件的状态非常有用
- 属性是只读,状态是可变的
- 状态改变,组件会重新渲染(父级属性变化,强制刷新也可以引起重新渲染)
- 引起组件重新渲染的条件
- state
- props
- 强制渲染. this.forceUpdate()
- 引起组件重新渲染的条件
class Cmp1 entends React.Component{
constructor(...args){
super(...args);
//状态初始化
this.state={a:0}
}
add(){
//修改状态
this.setState({
a:this.state.a+1
})
}
render(){
return <div>
//强制绑定add的this
<input type="button" value="+1" onClick={this.add.bind(this)} />
{this.state.a}
</div>
}
}
let comp=<Cmp1></Cmp1>
ReactDOM.render(comp,root)复制代码
注意⚠️:
- 状态的初始化只能放在constructor中完成
- 必须通过setState修改状态,否则也不能重新渲染——其实是setState在调用render
props变化引起的重新渲染
class Parent extends React.Component{
constructor(...args){
super(...args);
this.state={a:0}
}
render(){
return <div>
<input type="button" value="+1" onClick={function(){
this.setState({
a:this.state.a+1
})
}.bind(this)} />
<Child a={this.state.a} />
</div>
}
}
class Child extends React.Component{
constructor(...args){
super(...args);
}
render(){
return <div>
{this.props.a}
</div>
}
}
复制代码
强制渲染(forceUpdate)
class Cmp1 extends React.Component{
constructor(.;..args){
super(...args);
this.a=12;
}
fn(){
this.a++
//强制渲染
this.forceUpdate();
}
render(){
return <div>
<input type="button" value="+1" onClick={this.fn.bind(this)} />
{this.a}
</div>
}
}
复制代码
强制重新渲染会打乱React自身的渲染计划,轻则影响性能,重则引发错误,极少使用
组件生存周期
从组件创建到销毁的整个过程
上图中,涉及最重要的两个钩子函数, componentDidMount(组件已挂载)和 componentDidUpdate(组件已更新)
完整的生命周期钩子函数
创建阶段(mount)
- constructor:构造函数,这时还不算是个组件,只是class自身的初始化
- getDerivedStateFromProps:检查需要更新的状态(一个检查函数,不是钩子函数,检查更新,一般不做改变)
- render:初始渲染
- componentDidMount:组件创建完成,并已挂载到DOM结构中
更新阶段(update)
- getDerivedStateFromProps:检查
- shouldComponentUpdate:确定组件是否需要更新 (重要)有两个参数(nextProps,nextState)
- render
- getSnapshoutBeforeUpdate:更新前保存DOM状态
- compomentDidUpdate:组件已渲染完成
阻止更新
shouldComponentUpdata(nextProps,nextState){
//当前状态(变化前),新状态(变化后)
this.state.nextState
//当前属性,新属性
this.props.nextProps
return true -允许更新/。 false -拒绝更新
}复制代码
使用实例:阻止循环update
class Parent entends React.Component{
constructor(...args){
super(..args);
this.state={
id:1
}
}
next(){
this.setState{
id:this.state.id+1
}
}
render(){
return {
<div>
<input type="button" value="下一个" onClick={this.next.bind(this)}/>
<Child id={this.state.id}/>
</div>
}
}
}
class Child extends React.Component{
constructor(..args){
super(...args);
this.state={
name:'',
age:''
}
}
shouledComponentUpdata(nextProps,nextState){
//console.log(nextProps,this.props);
renturn{
//条件1:属性变了(来自父级)
nextProps.id!=this.props.id||
//条件2:状态变了(来自自己)
nextState.name!=this.state.name
};
}
loadData(id){
fetch(`data/data${id}.txt`).then(res=>{
res.json().then(data=>{
this.setState(data);
});
});
}
componentDidMount(){
console.log('初始:‘,this.props.id);
this.loadData(this.props.id)
}
componentDidUpdate(){
console.log('更新‘,this.props.id)
this.loadData(this.props.id);
}
render(){
console.log('渲染‘);
return (
<div>
ID:{this.props.id}<br/>
用户名:{this.state.name},年龄:{this.state.age}
</div>
)
}
}复制代码
销毁阶段(Unmount)
- componentWillUnmount:组织已销毁
销毁操作无法阻止