04setState方法自动赋值,改变状态,执行render,并进行渲染
自动化动态时钟的实现
实现:
//自动化时钟 时间(组件内部状态) / 秒针(状态) 自动化
class Clock extends React.Component{
constructor(props){
console.log('constructor--');
super(props)
// 01 state初始化状态=>通过this 挂载到组件实例上
this.state = {
time:new Date().toLocaleTimeString()
}
}
// 同上 直接写state不使用constructor效果一样
// state = {time:new Date().toLocaleTimeString}
render(){
console.log('render--');
return(
<div>
<h1>Clock</h1>
<h3>
time:{this.state.time}
</h3>
</div>
)
}
// 第一次渲染完毕会执行 数据已经挂载
componentDidMount(){
console.log('componentDidMount--');
setInterval(()=>{
//改变状态state里面的时间=>render重新渲染=>更新时间
//setState是react方法,将state里面对象替换掉,作用:改变状态,触发render重新执行
this.setState({time:new Date().toLocaleTimeString()})
},1000)
}
}
ReactDOM.render(<Clock />,document.getElementById("app"))
复盘分析
-
01利用props传递时间实现
//01 props传递时间
class Clock extends React.Component{
constructor(props){
// constructor执行一次
console.log('constructor--');
super(props)
this.time = new Date().toLocaleTimeString()
}
render(){
//render一直执行 执行多次
// render特点分析:
console.log('render--');
return(
<div>
<h1>Clock</h1>
<h3>
time:{this.time}
</h3>
</div>
)
}
componentDidMount(){
//componentDidMount执行一次
console.log('componentDidMount--');
setInterval(()=>{
// 能改变状态 但不能触发render执行
this.time = new Date().toLocaleTimeString()
},1000)
}
}
ReactDOM.render(<Clock />,document.getElementById("app"))
-
02自定义实例属性方式
不能触发render执行,render只能执行第一次,不能被componentDidMount触发再次执行 强制更新 (执行render)
// 02 自定义实例属性方式:不能触发render执行,render只能执行第一次,不能被componentDidMount触发再次执行 强制更新 (执行render)
class Clock extends React.Component{
constructor(props){
// constructor执行一次
console.log('constructor--');
super(props)
this.time = new Date().toLocaleTimeString()
this.state1 = {time:new Date().toLocaleTimeString()}
}
render(){
//render一直执行 执行多次
// render特点分析:
console.log('render--');
return(
<div>
<h1>Clock</h1>
<h3>
time:{this.state1.time}
</h3>
</div>
)
}
componentDidMount(){
//componentDidMount执行一次
console.log('componentDidMount--');
setInterval(()=>{
// 改变状态=>时间=>重新渲染=>更新时间
// 能改变状态 但不能触发render执行
this.state1 = ({time:new Date().toLocaleTimeString()})
// 验证状态是否改变
console.log(this);
// 打印状态真实值
console.log(this.state1);
// 强制更新
this.forceUpdate()
},1000)
}
}
ReactDOM.render(<Clock />,document.getElementById("app"))
02render不被触发时,控制台打印
02添加强制更新生效,控制台打印
-
03props发生改变,触发render执行
// 03 自动更新 props发生改变 执行render
class Clock extends React.Component{
constructor(props){
// constructor执行一次
console.log('constructor--');
super(props)
}
// props发生改变 render重新渲染,重新执行
render(){
console.log('render--');
return(
<div>
<h1>Clock</h1>
<h3>
time:{this.props.time}
</h3>
</div>
)
}
componentDidMount(){
//componentDidMount执行一次
console.log('componentDidMount--');
}
}
setInterval(()=>{
var e = <Clock time = {new Date().toLocaleTimeString()} />
ReactDOM.render(e,document.getElementById("app"))
},1000)
-
04setState方法自动赋值,改变状态,执行render,并进行渲染
// 04 setState
class N extends React.Component{
// 01 定义状态
state = {n:10}
render(){
console.log('render--');
console.log('render:',this.state.n);
return(
<div>
<h3>
N:{this.state.n}
</h3>
</div>
)
}
componentDidMount(){
//componentDidMount执行一次
console.log('componentDidMount--');
this.setState({
n:20
})
// 验证:setState()异步事件 this.setState=10
console.log("setState:",this.state);
// 同步异步先执行同步事件
}
}
ReactDOM.render(<N />,document.getElementById("app"))
04解决setState异步事件前,控制台打印
- 解决setState异步:
- 需求:setState执行之后直接获取值
- 解决:进入serState的回调函数,通过回调的
// 需求:setState执行之后直接获取值
// 解决:进入serState的回调函数,通过回调的方式,获取改变后的值
this.setState({n:20},()=>{
// 在改变完n值后执行回调函数
console.log("callback:",this.state.n);
})
// setState是同步还是异步的
// setState可能是异步的
04解决setState异步事件,callback回调控制台打印
-
render总结:
- forceUpdate强制执行=>不能改变状态但能执行render,需要手动赋值
- this.setState()自动赋值执行=>能改变状态 能执行render
- props变化=>能执行render
- 数据源头:
- state:自己的数据
- props:外面数据