React 类组件
类组件式我们经常用到的组件形式,也是React最基础的组件形式。类组件拥有自己的状态state(存储数据的仓库)和状态改变函数setState(在仓库中操作数据的管理人员),能够很方便地对页面上的数据进行各种操作。
函数式组件 + Hooks
函数式组件相对于类组件比较轻量,写起来也更加方便,在平常开发中更多的用在一些小的数据展示组件上面。但是,函数式组件它没有和类组件一样的state,setState,不能维持所谓的状态state。因此,在函数式组件中的数据操作显得比较复杂,一般需要调用父组件中的数据和数据操作函数。直到Hooks的出现,让函数式组件也可以像类组件一样拥有并维持自己的状态state以及改变自己的状态。
使用方法
函数式租价的基本结构就是一个方法(或者说是一个函数),这个函数相当于类组件中的render函数(渲染函数),因此函数式组件最关键的就是一定要有return值。
函数式组件格式1(基于TS)
import React from 'react'
// const 就是申明一个函数,然后再export暴露出去可以作为组件使用
// React.FC 的意思就是Function Components,也就是函数式组件,即指定了Count这个函数的类型
export const Count: React.FC = () => {
return (
<div>
hello world
<div>
)
}
函数式组件格式2(基于TS)
import React from 'react'
// const 就是申明一个函数,然后再export暴露出去可以作为组件使用
export function Count(){
return (
<div>
hello world
<div>
)
}
useState
用函数式组件和Hooks完成的计数器:
import React, { useState } from 'react'
import { Button } from 'antd';
export const Count: React.FC = () => {
// useState<number>(0) 中 <number>指定了数据类型,括号中的0就是计数器的初始值count
// [count, setCount] 是解构赋值,一个是申明变量count,另一个是申明修改变量的方法
// 其实就相当于类组件中的 state 和 setState
const [count, setCount] = useState<number>(0)
const increase = () => {
// setCount 括号中的值就是更新后的值,直接填入即可
setCount(count + 1)
}
const decrease = () => {
setCount(count - 1)
}
const reset = () => {
setCount(0)
}
return (
<>
<div>计数:{count}</div>
<div>
<Button type="primary" onClick={increase}>增加</Button>
<Button type="primary" onClick={decrease}>减少</Button>
<Button type="primary" onClick={reset}>重置</Button>
</div>
</>
)
}
这里还有一个改写方法,就是将关于数据count和数据操作都封装到另一个方法中去。不过好像没啥必要。再加上一层封装对安全性比较好,在实际中不需要这样。代码如下:
import React, { useState } from 'react'
import { Button } from 'antd';
export const Count: React.FC = () => {
const { count, increase, decrease, reset } = useCount();
return (
<>
<div>计数:{count}</div>
<div>
<Button type="primary" onClick={increase}>增加</Button>
<Button type="primary" onClick={decrease}>减少</Button>
<Button type="primary" onClick={reset}>重置</Button>
</div>
</>
)
}
function useCount() {
// useState<number>(0) 中 <number>指定了数据类型,括号中的0就是计数器的初始值count
// [count, setCount] 是解构赋值,一个是申明变量count,另一个是申明修改变量的方法
// 其实就相当于类组件中的 state 和 setState
const [count, setCount] = useState<number>(0)
const increase = () => {
// setCount 括号中的值就是更新后的值,直接填入即可
setCount(count + 1)
}
const decrease = () => {
setCount(count - 1)
}
const reset = () => {
setCount(0)
}
// 这里没有把setCount直接暴露出去,这样调用的时候只能进行+1,-1,归零这三种操作了。
return { count, increase, decrease, reset }
}
useEffect
在类组件中,存在render()渲染函数,构造器函数还有一些生命周期函数等等…,但是在函数式组件中没有生命周期,就需要使用useEffect来实现生命周期的功能。useEffect可以看成是componentDidMount
,componentDidUpdate
和 componentWillUnmount
这三个函数的组合。默认情况下,它在第一次渲染以及每次更新的时候都会执行。
你可以通知 React 跳过对 effect 的调用,只要传递数组作为 useEffect 的第二个可选参数即可,如果想执行只运行一次的 effect(仅在组件挂载和卸载时执行),可以传递一个空数组([]
)作为第二个参数。这就告诉 React 你的 effect 不依赖于 props 或 state 中的任何值,所以它永远都不需要重复执行。
代码示例:
export function Count3({ fatherCount,aa } : CountProps) {
const [count, setCount] = useState<number>(0)
// 在下面的useEffect中,设置只监听来自父组件的fatherCount发生变化时才会执行
useEffect(() => {
console.log(`父组件中的值发生了变化,新的值为${fatherCount}`)
},[fatherCount]);
const increase = () => {
setCount(count + 1)
}
const decrease = () => {
setCount(count - 1)
}
const reset = () => {
setCount(0)
}
return (
<>
<div>father:{fatherCount}</div>
<div>aa{aa}</div>
<div>计数:{count}</div>
<div>
<Button type="primary" onClick={increase}>增加</Button>
<Button type="primary" onClick={decrease}>减少</Button>
<Button type="primary" onClick={reset}>重置</Button>
</div>
</>
)
}
如果想要
useEffect
仅执行一次,那么就把useEffect的第二个参数设置为空数组([]
),如果想在渲染或父组件中的值发生变化(执行多次)就执行,那么就去掉第二个参数。