preface
The most important thing about React is components. Before React 16.8 (not Hooks yet), we wrote most of our applications as Class components, because Class components have a lifecycle and control state. But functional components can only stand back and say they are puppet components (also known as stateless components), calling props and presenting the UI
The following text is based on Hooks
The body of the
Are there any fundamental differences between functional components and class components?
Functional components capture values at render time
See this article: How is a functional component different from a class component?
Because React props are immutable, they never change. However, this is mutable
In fact, that’s what the class component this is for. React itself changes over time so that you can get the latest instances in the render method as well as in the lifecycle method
A functional component captures the value in its current state. If you use a timer to change the state of the current value, the functional component displays the original value, not the latest value. The class component always gets the latest value
The functional component captures the current value as soon as it is rendered. The class component is rendered, but its this points to the latest instance
Class components
You can see the online Demo
class ClassDemo extends React.Component { state = { value: "" }; ShowMessage = () => {alert(" latest value is "+ this.state.value); }; handleMessageChange = (e) => { this.setState({ value: e.target.value }); }; handleClick = () => { setTimeout(this.showMessage, 3000); }; render() { return ( <div> <input value={this.state.value} onChange={this.handleMessageChange} /> <button OnClick ={this.handleClick}> click </button> </div>); }}Copy the code
The result is a click to get the most recent value, not the value three seconds ago. Why is that? Since this is mutable, alert(” last value is “+ this.state.value) is executed after 3 seconds. This.state. value points to the latest value
What if a class component wants to save the original value?
Read this.props before calling the event
You can see the online Demo
ShowMessage = (value) => {alert(" new value = "+ value); }; handleClick = () => { const { value } = this.state; setTimeout(() => this.showMessage(value), 3000); };Copy the code
It works, but when clicked it gets the current user, which is passed to this.showMessage, so that the value remains the same even 3 seconds later
Cons: Every time you need to get a value from this.props, if there is too much data, it is not human to write
2. Bind methods in constructors
You can see the online Demo
constructor(props) {
super(props);
this.showMessage = this.showMessage.bind(this);
this.handleClick = this.handleClick.bind(this);
}
Copy the code
This method won’t solve the problem. Our problem was that we read the data from this.props too late — it wasn’t the context we needed to use when we read it
Use closures
Write methods into render so that each render captures the props or state being used at the time
You can see the online Demo
class ClassDemo extends React.Component { state = { value: "" }; render() { const { value } = this.state; Const showMessage = () => {alert(" new value = "+ value); }; const handleMessageChange = (e) => { this.setState({ value: e.target.value }); }; const handleClick = () => { setTimeout(showMessage, 3000); }; return ( <div> <input value={this.state.value} onChange={handleMessageChange} /> <button OnClick ={handleClick}> click </button> </div>); }}Copy the code
But that’s silly. What’s the difference between this and a functional component? Instead, use functional components
Functional components that want to keep the latest values
Use useRef to save the most recent value and let the component get the most recent value
function MyComponent() {
const ref = useRef(null);
}
Copy the code
First, a REF plays the same role as an instance; the REF object is a container with the current property
We could have written the last example using functional components like this:
const FunctionDemo = () => { const [value, setValue] = useState(""); const refValue = useRef(""); Const showMessage = () => {alert(" last value = "+ refvalue.current); }; const handleMessageChange = (e) => { setValue(e.target.value); refValue.current = e.target.value; }; const handleClick = () => { setTimeout(showMessage, 3000); }; <div> <input value={value} onChange={handleMessageChange} /> <button onClick={handleClick}> click </button> </div> ); };Copy the code
You can see the online Demo
Here I put forward two questions:
- Why does ref hold the latest value?
- Why are functional components captured, but class components not?
The author’s answer will be given in subsequent articles
The resources
- How is a functional component different from a class component?