一、setState
state状态必须通过setState进行更新,且更新是一种合并,不是替换。
下面通过一个切换状态的例子说明
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello_react</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="/react-development.js"></script>
<!-- 引入react-dom,用于支持react操作DOM -->
<script type="text/javascript" src="/react-dom-development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script type="text/javascript" src="/babel.min.js"></script>
<script type="text/babel">
// 1.创建组件
class Weather extends React.Component {
// 构造器调用一次
constructor(props) {
super(props)
this.state = { isHot: false,wind: "微风" }
this.switchover = this.switchover.bind(this)
}
// render调用1+n次
render() {
const { isHot,wind } = this.state
return <h1 onClick={this.switchover}>今天天气很{isHot ? '炎热' : '凉爽'},{wind}</h1>
}
// 点几次就调几次
switchover() {
// 由于changeWeather作为onClick的回调,所以不是通过实例调用的,是直接调用
// 类中的方法默认开启了局部的严格模式,所以switchover中的this为undefined
const isHot = this.state.isHot
// 注意:状态必须通过setState进行更新,且更新是一种合并,不是替换
this.setState({isHot: !isHot})
// 严重注意:状态不可以直接更改,下面这行就是直接更改!!!
// this.state.isHot = !isHot
}
}
// 2.渲染虚拟DOM到页面
ReactDOM.render(<Weather />, document.getElementById('test'))
</script>
</body>
</html>
1.通过ES6的语法:class类来创建一个类式组件,该类继承自父类React.Component。
2.该类式组件中定义一个构造器,在构造器中必须调用super(props)这方法,且该方法必须是在自定义属性之前调用。
3.在构造器里面定义一个状态state,该state是在父类身上的,子类是通过实例对象沿着原型链获取到父类的state,即this.__props__state,__props__可以省略不写---》this.state。
4一开始state是为null,所以我们开发者可以给state赋值,将状态在页面渲染。
上面的例子中定义了一个state对象,该对象有isHot和wind属性,即this.state = {isHot: false,wind: '微风'},然后在页面中渲染。
然后定义一个切换方法switchover对状态进行改变。
重点:如何修改state?
1)首先在元素中绑定点击事件:在原始html中是使用onclick,而在react中是使用onClick,这里要注意。
2)通过onClick来绑定switchover事件,但在switchover中如何修改?里面的this指向的是谁?
答:由于switchover作为onClick的回调,所以不是通过实例调用的,是直接调用,而在类里面定义的方法,默认是开启了严格模式,所以方法里面的this谁都不指向,为undefined。所以此时switchover里面的this为undefined。
我们要修改state状态,就要拿到state,而state在实例对象上,所以要想办法将switchover里面的this指向实例对象。
3)那么通过bind()方法来改变this的指向,并返回新的函数。
在构造器里面实现this.switchover = this.switchover.bind(this),此时的this是实例对象,这样就将类中定义的switchover方法里面的this指向实例对象,并定义一个同名的实现来接收,这样onClick绑定的就是构造器定义的switchover。那么状态就可以通过setState进行更新,且更新是一种合并,不是替换。