学习目标
-
setState
-
事件绑定
实例一 初始化组件
import React from 'react';
import ReactDOM from 'react-dom';
class Clock extends React.Component {
constructor(props) {
super(props)
// React的状态,相当于VUE的数据,状态变更会导致View被重新渲染
this.state = {
time: new Date().toLocaleTimeString()
}
console.log(this.state)
}
render() {
return (
<div>
<h1>当前时间:{this.state.time}</h1>
</div>
)
}
}
ReactDOM.render(
<Clock />,
document.querySelector('#root') //寻找文件对象
)
setInterval(() => {
ReactDOM.render(
<Clock />,
document.querySelector('#root') //寻找文件对象
)
console.log(new Date().toLocaleTimeString())
}, 1000);
打印窗口中时间每隔1s打印一次,但不会每隔1s渲染一次组件。因此组件中的打印也不会每隔1s就执行一次,也就是初始化没有改变。
ReactDOM反复渲染同一个组件,不会重新进行初始化。构造函数只执行一次,console.log(this.state) 只会执行一次。
render函数会每隔1s就渲染一次
import React from 'react';
import ReactDOM from 'react-dom';
class Clock extends React.Component {
constructor(props) {
super(props)
// React的状态,相当于VUE的数据,状态变更会导致View被重新渲染
this.state = {
time: new Date().toLocaleTimeString()
}
console.log(this.state)
}
render() { // 每次都会加载
this.state.time = new Date().toLocaleTimeString();
return (
<div>
<h1>当前时间:{this.state.time}</h1>
</div>
)
}
}
ReactDOM.render(
<Clock />,
document.querySelector('#root') //寻找文件对象
)
setInterval(() => {
ReactDOM.render(
<Clock />,
document.querySelector('#root') //寻找文件对象
)
console.log(new Date().toLocaleTimeString())
}, 1000);
构造函数不会反复调用,是因为React认为是同一个组件,就不会重新实例化对象,但是会调用原型(render函数)。
实例二 componentDidMount
import React from 'react';
import ReactDOM from 'react-dom';
class Clock extends React.Component {
constructor(props) {
super(props)
// React的状态,相当于VUE的数据,状态变更会导致View被重新渲染
this.state = {
time: new Date().toLocaleTimeString()
}
console.log(this.state)
}
render() {
this.state.time = new Date().toLocaleTimeString();
return (
<div>
<h1>当前时间:{this.state.time}</h1>
</div>
)
}
//生命周期函数,组件渲染完成时的函数
componentDidMount() {
setInterval(() => {
console.log(this.state.time)
this.state.time = new Date().toLocaleTimeString();
ReactDOM.render(
<Clock />,
document.querySelector('#root')
)
}, 1000);
}
}
ReactDOM.render(
<Clock />,
document.querySelector('#root') //寻找文件对象
)
componentDidMount在渲染后执行,实现每隔1s渲染一次。但是官方不推荐此做法,推荐使用setState。
实例三 setState() 重新渲染
import React from 'react';
import ReactDOM from 'react-dom';
class Clock extends React.Component {
constructor(props) {
super(props)
// React的状态,相当于VUE的数据,状态变更会导致View被重新渲染
// 构造函数初始化数据,将需要改变的数据初始化到state中
this.state = {
time: new Date().toLocaleTimeString()
}
console.log(this.state)
}
render() {
this.state.time = new Date().toLocaleTimeString();
return (
<div>
<h1>当前时间:{this.state.time}</h1>
</div>
)
}
//生命周期函数,组件渲染完成时的函数
componentDidMount() {
setInterval(() => {
console.log(this.state.time)
// this.state.time = new Date().toLocaleTimeString(); //错误的方式
//切勿直接修改state数据,直接state重新渲染内容,需要使用setState
// 通过this.setState修改完数据后,不会立即修改视图(DOM)里的内容
// React会在this.setState内容所有设置状态改变后,统一对比虚拟DOM对象,然后统一修改,提升性能。
// 小程序也是借鉴REACT状态管理操作
this.setState({
time: new Date().toLocaleTimeString()
})
console.log(this.state.time)
}, 1000);
}
}
ReactDOM.render(
<Clock />,
document.querySelector('#root') //寻找文件对象
)
componentDidMount中2个console.log(this.state.time)输入结果相同。
实例四 this (输出undefined)
import React from 'react';
import ReactDOM from 'react-dom';
import './Tab.css'
class Tab extends React.Component {
constructor(props) {
super(props);
// 设置状态(数据)
this.state = {
c1: "",
c2: ""
}
}
clickEvent(e) {
console.log(e.target)
console.log(e.target.dataset.index)
console.log(this) // undefined
if (e.target.dataset.index == 1) {
this.state({
c1:"content active",
c2:"content"
})
} else {
this.state({
c1:"content",
c2:"content active"
})
}
}
render() {
return (
<div>
<button data-index="1" onClick={this.clickEvent}>内容一</button>
<button data-index="2" onClick={this.clickEvent}>内容二</button>
<div className={this.state.c1}>
<h1>内容1</h1>
</div>
<div className={this.state.c2}>
<h1>内容2</h1>
</div>
</div>
)
}
}
ReactDOM.render(
<Tab />,
document.querySelector('#root') //寻找文件对象
)
onClick={this.clickEvent}>,console.log(this) this对应的是点击事件里的this。如何解决该问题?绑定事件。
添加this绑定,解决以上问题
import React from 'react';
import ReactDOM from 'react-dom';
import './Tab.css'
class Tab extends React.Component {
constructor(props) {
super(props);
// 设置状态(数据)
this.state = {
c1:"content active",
c2:`content`
}
this.clickEvent = this.clickEvent.bind(this)
}
clickEvent(e) {
let index = e.target.dataset.index
if (index === '1') {
this.setState({
c1:"content active",
c2:`content`
})
} else {
this.setState({
c1:'content',
c2:'content active'
})
}
}
render() {
return (
<div>
<button data-index="1" onClick={this.clickEvent}>内容一</button>
<button data-index="2" onClick={this.clickEvent}>内容二</button>
<div className={this.state.c1}>
<h1>内容1</h1>
</div>
<div className={this.state.c2}>
<h1>内容2</h1>
</div>
</div>
)
}
}
ReactDOM.render(
<Tab />,
document.querySelector('#root') //寻找文件对象
)