How to create a function component
- Arrow function form
const Hello = (props) => { return <div>{props.message}</div> } // Can be abbreviated as const Hello = props => <div>{props.message}</div>
- function form
function Hello(props) { return <div>{props.message}</div> }
Function components have less code than class components
Take a look at this example and implement + 1 as well
class component
class App extends React.Component { constructor(props) { super(props); this.state = { n: 1 } } click = () => { this.setState(state => ({ n: state.n + 1 })) } render() { return ( <div> {this.state.n} <button onClick={this.click}>+1</button> </div> ) } }
Function component
const App = props => { const [n, setN] = useState(0) const click = () => { setN(n + 1) } return ( <div> {n} <button onClick={click}>+1</button> </div> ) }
It seems that functional components really have great advantages
Can I use a function component instead of a class component?
Faced with two problems
- Function component has no state
- Function component has no lifecycle
What if there's no State?
React v16.8.0 introduces Hooks API, one of which is called useState to solve the problem
import React, { useState } from 'react'; function Example() { // Declare a state variable called "count" const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
What if there is no life cycle?
React v16.8.0 introduces Hooks API, one of which is called useEffect, which can solve the problem
- Simulate componentDidMount
useEffect(()=> { console.log('First render') }, []) // When the first parameter is [], the function is executed only once at the beginning
The second parameter of useEffect is the state attribute to be monitored. If omitted, it means to monitor the changes of all state attributes. If empty, it means not to monitor any state attributes
If you specify the to listen state Object, then only this one will be monitored state Properties. Changes in other properties will not trigger the execution of the function
- Simulate componentDidUpdate
useEffect(() => { console.log('Any attribute change') }) useEffect(()=> { console.log('n Changed') }, [n]) // Listen for all properties when the second parameter is not passed in // When [n] is passed in, only n is listened to
However, this does not really simulate componentDidUpdate, because it will not be executed at the first rendering, and the above code cannot do this
So in order to fix this problem, we need to add some code
const [nUpdateCount, setNUpdateCount] = useState(0) useEffect(() => { setNUpdateCount(nUpdateCount => nUpdateCount + 1) }, [n]) useEffect(() => { if (nUpdateCount > 1) { console.log('Updated once') } }, [nUpdateCount])
We can pass nUpdateCount To solve this problem, nupdatecount Detected n The first change, heavy 0 Become 1, and useEffect Medium judgment nUpdateCount greater than one Start execution only when
However, such code seems to be a little cumbersome and can continue to be optimized
Write a useUpdate Function, fn Is the function executed during update, and dey is the listening object. This function can be extracted and processed from components and directly applied when in use
const useUpdate = (fn, dey) => { const [count, setCount] = useState(0) useEffect(() => { setCount(count => count + 1) }, [dey]) useEffect(() => { if (count > 1) {fn()} }, [count, fn]) }
Directly called in component useUpdate
useUpdate(() => {console.log('Updated once')}, n)
- Simulate componmentWillUnmount
useEffect(() => { console.log('The data is updated') return () => { console.log("I'm going to be destroyed") } })
useEffect can return another function, which will be called when the component disappears, while console.log('data updated ') will be called when the component changes and re renders
- Simulate shouldComponentUpdate
const MyComponent = React.memo( _MyComponent, (prevProps, nextProps) => nextProps.count !== prevProps.count )
React.memo wraps a component for shallow comparison of its props, but it is not a hooks because its writing is different from hooks. In fact, react.memo is equivalent to PureComponent, but it only compares props.