React 函数组件

49 阅读3分钟

创建方式


const Hello = (props)=>{

return <div>{props.message}</div>

}

const Hello = props => <div>{props.message}</div>

function Hello(props){

return <div>{props.message}</div>

}

函数组件代替Class组件

面临两个问题:

  1. 函数组件没有State

  2. 函数组件没有生命周期

React推出了Hooks API,其中的useState和useEffect可以解决这两个问题

依然拿+1的这个案例,首先用class组件写一遍,

image.png

可以发现有很多固定的格式写法,实现这样一个简单的功能代码量也比较多。接下来用函数组件写法写一次进行对比。

image.png

可以看出从代码复杂程度来看函数组件相比Class组件更加简洁好读一点。

useState

React v16.8.0推出了Hooks API 其中的useState可以类比class组件的state

const [n, setN] = React.useState(0)

其中useState返回两个API,n用来读,setN用来写(名字可以自定义,前面的用来读后面的用来写),后面跟的参数是初始化state的值图中的webstorm也有提示。

此外函数组件消除了this

useEffect

React v16.8.0推出了Hooks API 其中的useEffect可以类比class组件的生命周期

模拟componentDidMount

如果直接在函数内定义一个方法,那么它每次更新都会调用,不能做到只有第一次渲染时调用,所以需要用到uesEffect

image.png

默认情况下和写在外面差不多,如果需要只是第一次渲染,这时用到useEffect第二个参数,写一个空数组即可。

useEffect(()=>{console.log('第一次渲染')},[])

模拟componentDidUpdate

useEffect(()=>{console.log('任意属性变更')})

useEffect(()=>{console.log('n变了')},[n])

比如我想实现在n变化了的时候进行更新,那么

image.png

在第二个参数的数组里写入那个监听的变化对象,比如在n变化的时候更新,那么就在数组里写入n

如果数组里面包含了全部的state那么可以省略不写,则是任何state变化了都会对这个方法进行调用

模拟componentWillUnmount

useEffect(()=>{

console.log('第一次渲染')

return ()=>{

console.log('组件要死了')

}

})

image.png

用一个新的案例来展示,点击隐藏或显示,隐藏时相当于组件被销毁了。如果我们想模拟组件销毁的生命周期钩子,需要在useEffect内返回一个函数,这个返回的函数会在组件销毁时运行。

模拟其他的生命周期

constructor

函数组件执行的时候就相当于consturctor

shouldComponentUpdate

运用React.memouseMemo

render

函数组件的返回值就是render

自定义Hook之useUpdate

在模拟componentDidUpdate时第一次变化也算更新渲染,(比如上述例子的+1变化,因为初始时从undefined变成0也会换变化)为了让其第一次不算更新渲染,我们可以使用一个自定义Hook

image.png 声明一个变量用来记录更新次数。用useEffect来实现n变化了更新次数+1。再用useEffect来实现更新次数nUpdateCount变化了且大于1时打印出“变化了”,即可消除初始的渲染提示。

对代码进行重构

image.png

实现了自定义Hook

再把这段代码单独放一个文件再引用。

image.png