在React中,state是组件中存储和管理数据的一种方式。
它是一个JavaScript对象,用于存储组件的状态信息。当state发生变化时,React会重新渲染组件,从而更新用户界面。
在React中,有两种类型的组件:函数组件(Function Component)和 类组件(Class Component)。
函数组件
- 简单,易于理解和编写。
- 无状态,即不能使用state。
- 无生命周期方法,即无法使用
componentDidMount
、componentDidUpdate
等生命周期方法。 - 可以使用Hooks(React 16.8引入)来管理状态和生命周期。
以下是使用函数组件和useState Hook的示例:
import React, { useState } from 'react';
function Counter () {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
const decrement = () => {
setCount(count - 1);
};
return (
<div>
<h1>Counter: {count}</h1>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
);
}
export default Counter;
类组件
- 相对复杂,需要定义一个继承自React.Component的类。
- 有状态,可以使用state来管理组件内部的状态。
- 可以使用生命周期方法,如
componentDidMount
、componentDidUpdate
等。 - 不支持Hooks。
import React, { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
this.increment = this.increment.bind(this);
this.decrement = this.decrement.bind(this);
}
increment () {
this.setState({ count: this.state.count + 1 });
};
decrement () {
this.setState({ count: this.state.count - 1 });
};
render () {
return (
<div>
<h1>Counter: {this.state.count}</h1>
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
</div>
);
}
}
export default Counter;
上例中的 increment 和 decrement 方法是在button元素的onClick事件处理器中被调用的(是作为一个普通函数被调用的,而不是作为组件实例的方法被调用)。
由于该自定义方法没有被绑定到组件实例,this将不再指向组件实例,而是指向undefind(类函数中的方法才用严格模式,this指向undefined)
需要通过bind(this)
改变this指向为类的实例化对象
简写形式:
- 省去constructor构造器,state 移出
- 自定义方法要:用赋值语句的形式 + 箭头函数(使this指向上下文,即构造函数的实例化对象)。
成为实例上的方法,这样就不是bind改变this指向。
import React, { Component } from 'react';
class Counter extends Component {
state = {
count: 0
};
increment = () => {
this.setState({ count: this.state.count + 1 });
};
decrement = () => {
this.setState({ count: this.state.count - 1 });
};
render () {
return (
<div>
<h1>Counter: {this.state.count}</h1>
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
</div>
);
}
}
export default Counter;