一. 如何创建一个函数组件
const Hello=(props)=>{
return <div>{props}</div>
}
const Hello=props=>
<div>{props}</div>
const Hello(props){
return <div>{props}</div>
}
例:
import React from 'react'
const App = props => {
const [n, setN] = React.useState(0)
const onClick = () => {
setN(n + 1)
}
return (
<div>
{n}
<button onClick={onClick}>+1</button>
</div>
)
}
export default App
二. Hooks API
我们使用函数组件可以使得代码量更加简洁,但是函数组件没有class组件的生命周期和state,当然state我们使用了一个React.useState,这是v16.8.0,React提供的一个API,接下来我们就介绍一下Hook API如何模拟生命周期
1. 模拟componentDidMount和componentDidUpdate
useEffect(()=>{
console.log(1)
},[])
//这个函数的第二个参数为[]
这个[]代表的是你需要监听的state对象,如果省略则默认监听所有state变化,如果为空则表示任何state变化我都不执行,如果有多个state而数组中只写了一个,那么只会在此变量变化时触发函数
import React,{useState,useEffect} from 'react'
const App = props => {
const [n, setN] = useState(0)
const [m, setM] = useState(0)
const onClick = () => {
setN(n + 1)
}
const onClickM = () => {
setM(m + 1)
}
useEffect(()=>{
console.log(1)
},[n])
//只在n变化时调用
return (
<div>
{n}
<button onClick={onClick}>+1</button>
<hr/>
{m}
<button onClick={onClickM}>+1</button>
</div>
)
}
export default App
由于componentDidUpdate在第一次渲染不执行,之后发生变化才执行,所以我们要修复这个问题
const useUpdate = (fn, dep) => {
const [count, setCount] = useState(0)
useEffect(() => {
setCount(x => x + 1)
}, [dep])
useEffect(() => {
if (count > 1) {
fn()
}
}, [count, fn])
}
useUpdate(() => {
console.log(`${n}`+Math.random())
}, n)
这里就相当于自定义了一个Hook API,初次渲染不触发更新
2. 模拟componentWillUnmount
useEffect(()=>{
console.log(1)
return ()=>{
console.log('销毁时调用')
}
})
useEffect可以再返回一个函数,他会在组件消失时调用,而console.log(1)则会在组件发生变化重渲染时调用
3. 模拟shouldComponentUpdate
使用React.memo(useMemo)解决
函数组合
import React from 'react'
const X=()=>{
return <div>x</div>
}
const Y=()=>{
return <div>y</div>
}
const App = props => {
return (
<>
<X/>
<Y/>
</>
)
}
export default App
可以将多个组件加入一个App组件中返回