有状态属性的组件,props像传入的参数,state更像组件的“内存”。
// 创建状态(state)
// 通过继承 React.Component,类组件可创建state,在类内任意调用
class StatefulComponent extends React.Component {
constructor(props) {
super(props);
// 只修改这一行下面的代码
this.state = {
firstName: 'Wang'
}
// 只修改这一行上面的代码
}
render() {
const name=this.state.name;
return (
<div>
{/*也可以填入上方Render内定义的 name 变量*/}
<h1>{this.state.firstName}</h1>
</div>
);
}
};
------------------
// React 要求永远不要直接修改 state,而是在 state 发生改变时始终使用 this.setState()。
this.setState({
username: 'Lewis'
});
------------------
// 有时,在更新状态时,您可能需要知道以前的状态。然而,状态更新可能是异步的-这意味着
// React可以将多个setState()调用批处理到单个更新中。这意味着在计算下一个值时不能
// 依赖于this.state或this.props的前一个值。所以,你不应该使用这样的代码:
this.setState({
counter: this.state.counter + this.props.increment
});
// 正确的做法是,给 setState 传入一个函数,这个函数可以访问 state 和 props。
// 给 setState 传入函数可以保证 state 和 props 是正确的值。 代码可以重写为这样:
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
------------------review
// Counter 组件跟踪 state 中的 count 值。 有两个按钮分别调用 increment() 和 decrement() 方法。
// 编写这些方法,使计数器值在单击相应按钮时增加或减少 1。 另外,创建一个 reset() 方法,当单击
// reset 按钮时,把计数设置为 0。
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
// 修改这行下面的代码
this.increment = this.increment.bind(this); // 创建绑定
this.decrement = this.decrement.bind(this);
this.reset = this.reset.bind(this);
// 修改这行上面的代码
}
// 修改这行下面的代码
increment() {
this.setState((state) => ({
count: state.count + 1
}));
}
decrement() {
this.setState((state) => ({
count: state.count - 1
}));
}
reset() {
this.setState((state) => ({
count: 0
}));
}
// 修改这行上面的代码
render() {
return (
<div>
<button className='inc' onClick={this.increment}>Increment!</button>
<button className='dec' onClick={this.decrement}>Decrement!</button>
<button className='reset' onClick={this.reset}>Reset</button>
<h1>Current Count: {this.state.count}</h1>
</div>
);
}
};
合state进行更复杂的UI交互
// 与输入框联动
class ControlledInput extends React.Component {
constructor(props) {
super(props);
this.state = {
input: ''
};
// 修改这行下面的代码
this.handleChange = this.handleChange.bind(this);
// 修改这行上面的代码
}
// 修改这行下面的代码
handleChange(event) {
this.setState({
input: event.target.value
})
}
// 修改这行上面的代码
render() {
return (
<div>
{ /* 修改这行下面的代码 */}
<input value={this.state.input}
onChange={this.handleChange}/>
{ /* 修改这行上面的代码 */}
<h4>Controlled Input:</h4>
<p>{this.state.input}</p>
</div>
);
}
};
Q:react现在是否还以class组件为主?还是以函数组件为主
A: 类组件(Class Components)
类组件是React早期版本中创建组件的主要方式。它们是ES6类的实例,继承自React.Component,并包含一个render()方法,该方法返回JSX。
定义和语法: 类组件使用ES6类语法定义,需要继承自React.Component,并在类中实现render()方法。例如:
jsx
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
状态管理: 类组件通过this.state和this.setState()管理内部状态。
生命周期方法: 类组件提供了多种生命周期方法,如componentDidMount、componentDidUpdate和componentWillUnmount,允许开发者在组件生命周期的不同阶段执行副作用。
引用处理: 类组件通常使用React.createRef()来处理引用,从而可以直接访问DOM元素。
性能: 由于类组件的额外开销,如类实例化和方法调用,它们的性能通常略低于函数组件。
函数组件(Functional Components)
函数组件是React中较新的组件形式,它们本质上是JavaScript函数,接收props作为参数,并返回JSX。
定义和语法: 函数组件使用JavaScript函数定义,更简洁,易于理解。例如:
jsx
function Greeting(props) {
return <h1>Hello, {props.name}</h1>;
}
Hooks: 自React 16.8起,函数组件通过Hooks获得了管理状态和副作用的能力。例如,useState用于状态管理,useEffect用于生命周期方法。
简化语法: 函数组件避免了类组件中this的复杂性,代码更简洁。
性能: 函数组件通常提供更好的性能,因为它们避免了类继承的开销。
社区偏好: 根据社区使用趋势,函数组件的使用率从2018年的45%增长到2022年的92%,显示出明显的增长趋势。