ReactJS - 静态 getDerivedStateFromProps() 方法



React 是一个著名的 JavaScript 库,用于创建用户界面。React 中有一个名为 getDerivedStateFromProps 的方法看起来很复杂,但让我们把它分解成简单的词。

在 React 中,getDerivedStateFromProps 方法在组件渲染之前被调用,无论是在它首次出现时还是在它更新时。它的目标是找出组件的状态需要随着其 props 的变化而改变。

语法


static getDerivedStateFromProps(props, state)

参数

  • props - 组件将用于渲染的下一组属性。
  • state - 组件将要呈现的状态。

返回值

如果需要更新状态,它应该返回一个对象;否则,它应返回 null。

例子

示例 1

让我们使用 getDerivedStateFromProps 函数创建一个简单的 React 应用程序。在此示例中,我们将创建一个表单,当用户 ID 更改时,该表单会自动刷新电子邮件地址。


import React, { Component } from 'react';

class Form extends Component {
	 	state = {
	 	 	 email: this.props.defaultEmail,
	 	 	 prevUserID: this.props.userID
	 	}; 		
	 	static getDerivedStateFromProps(props, state) {
	 	 	 if (props.userID !== state.prevUserID) {
	 	 	 	 	return {
	 	 	 	 	 	 prevUserID: props.userID,
	 	 	 	 	 	 email: props.defaultEmail
	 	 	 	 	};
	 	 	 }
	 	 	 return null;
	 	} 		
	 	handleUserIDChange = (e) => {
	 	 		
	 	 	 // Simulate user ID change
	 	 	 this.props.onUserIDChange(e.target.value);
	 	};
	 	
	 	handleEmailChange = (e) => {
	 	 	 this.setState({ email: e.target.value });
	 	};
	 	
	 	render() {
	 	 	 return (
	 	 	 	 	<div>
	 	 	 	 	 	 <label>
	 	 	 	 	 	 	 	User ID:
	 	 	 	 	 	 	 	<input type="text" value={this.props.userID} onChange={this.handleUserIDChange} />
	 	 	 	 	 	 </label>
	 	 	 	 	 	 <br />
	 	 	 	 	 	 <label>
	 	 	 	 	 	 	 	Email:
	 	 	 	 	 	 	 	<input type="text" value={this.state.email} onChange={this.handleEmailChange} />
	 	 	 	 	 	 </label>
	 	 	 	 	</div>
	 	 	 );
	 	}
}

class App extends Component {
	 	state = {
	 	 	 userID: '123',
	 	 	 defaultEmail: 'user@example.com'
	 	};
	 	
	 	handleUserIDChange = (newUserID) => {
	 	 	 this.setState({ userID: newUserID });
	 	};
	 	
	 	render() {
	 	 	 return (
	 	 	 	 	<div>
	 	 	 	 	 	 <h1>Form App</h1>
	 	 	 	 	 	 <Form
	 	 	 	 	 	 	 	userID={this.state.userID}
	 	 	 	 	 	 	 	defaultEmail={this.state.defaultEmail}
	 	 	 	 	 	 	 	onUserIDChange={this.handleUserIDChange}
	 	 	 	 	 	 />
	 	 	 	 	</div>
	 	 	 );
	 	}
}

export default App;

输出

表单应用程序

在上面的示例中,表单组件具有用户 ID 和电子邮件输入。当用户 ID 更改时,getDerivedStateFromProps 函数将重置电子邮件。函数 handleUserIDChange 模拟用户 ID 更改。App 组件设置表单并管理对用户 ID 的更改。这是一个基本示例,我们可以对其进行更改以满足我们的特定要求。

示例 2

现在,我们将创建一个简单的计数器应用程序,其中初始计数作为参数给出,并且计数器可以递增。当属性更改时,将调用 getDerivedStateFromProps 函数来更新状态。


import React, { Component } from 'react';
import './App.css';

class Counter extends Component {
	 	state = {
	 	 	 count: this.props.initialCount,
	 	};
	 	
	 	static getDerivedStateFromProps(props, state) {
	 	 	 // Check if the initial count prop has changed
	 	 	 if (props.initialCount !== state.count) {
	 	 	 	 	// Update the state with the new initial count
	 	 	 	 	return {
	 	 	 	 	 	 count: props.initialCount,
	 	 	 	 	};
	 	 	 }
	 	 	 return null;
	 	}
	 	
	 	handleIncrement = () => {
	 	 	 this.setState((prevState) => ({
	 	 	 	 	count: prevState.count + 1,
	 	 	 }));
	 	};
	 	
	 	render() {
	 	 	 return (
	 	 	 	 	<div>
	 	 	 	 	 	 <p>Count: {this.state.count}</p>
	 	 	 	 	 	 <button onClick={this.handleIncrement}>Increment</button>
	 	 	 	 	</div>
	 	 	 );
	 	}
}

class App extends Component {
	 	state = {
	 	 	 initialCount: 0,
	 	};
	 	
	 	handleInitialCountChange = (e) => {
	 	 	 const newInitialCount = parseInt(e.target.value, 10);
	 	 	 this.setState({ initialCount: newInitialCount });
	 	};
	 	
	 	render() {
	 	 	 return (
	 	 	 	 	<div className='App'>
	 	 	 	 	 	 <h1>Counter App</h1>
	 	 	 	 	 	 <label>
	 	 	 	 	 	 	 	Initial Count:
	 	 	 	 	 	 	 	<input
	 	 	 	 	 	 	 	 	 type="number"
	 	 	 	 	 	 	 	 	 value={this.state.initialCount}
	 	 	 	 	 	 	 	 	 onChange={this.handleInitialCountChange}
	 	 	 	 	 	 	 	/>
	 	 	 	 	 	 </label>
	 	 	 	 	 	 <Counter initialCount={this.state.initialCount} />
	 	 	 	 	</div>
	 	 	 );
	 	}
}

export default App;

输出

初始计数

现在,我们有一个简单的 React 应用程序,其中计数器根据初始 count 属性进行更新,并使用 getDerivedStateFromProps 方法来处理属性更改。

示例 3

让我们创建一个简单的 React 应用程序,它使用生命周期方法 getDerivedStateFromProps 根据用户是否已登录来显示消息。因此,在运行应用程序后,我们将能够看到用户已登录或注销的消息。


import React, { Component } from 'react';
import './App.css';

class LoginStatus extends Component {
	 	static getDerivedStateFromProps(props, state) {
	 	 	 // Check if the user is logged in
	 	 	 const isLoggedIn = props.isLoggedIn;
	 	 	 // Display different messages as per the login status
	 	 	 return {
	 	 	 	 	statusMessage: isLoggedIn ? 'Welcome back! You are logged in.' : 'Please log in.'
	 	 	 };
	 	}
	 	
	 	render() {
	 	 	 return (
	 	 	 	 	<div>
	 	 	 	 	 	 <p>{this.state.statusMessage}</p>
	 	 	 	 	</div>
	 	 	 );
	 	}
}

class App extends Component {
	 	state = {
	 	 	 isLoggedIn: false
	 	};
	 	
	 	handleLoginToggle = () => {
	 	 	 this.setState((prevState) => ({
	 	 	 	 	isLoggedIn: !prevState.isLoggedIn
	 	 	 }));
	 	};
	 	
	 	render() {
	 	 	 return (
	 	 	 	 	<div className='App'>
	 	 	 	 	 	 <h1>Login App</h1>
	 	 	 	 	 	 <button onClick={this.handleLoginToggle}>
	 	 	 	 	 	 {this.state.isLoggedIn ? 'Logout' : 'Login'}
	 	 	 	 	 	 </button>
	 	 	 	 	 	 <LoginStatus isLoggedIn={this.state.isLoggedIn} />
	 	 	 	 	</div>
	 	 	 );
	 	}
}

export default App;

输出

登录应用程序

在上面的应用程序中,我们使用了 getDerivedStateFromProps() 方法来检查用户的登录和注销状态。正如我们在上面的输出中看到的,屏幕上会显示一个按钮,当我们单击该按钮时,它将显示消息“欢迎回来!您已登录。该按钮将更改为注销。

局限性

与前一种 UNSAFE_componentWillReceiveProps 不同,它在每次渲染时都会被调用。

它无法访问组件实例,因此我们不能直接在其中使用它。

总结

getDerivedStateFromProps 函数乍一看可能很困难,但它是针对特定条件的工具。从根本上说,它允许我们根据其属性的变化来管理组件的状态。