前言:
市面上对怎么使用React Hooks新特性的入门例子可以说是汗牛充栋,我都懒得写这些脱裤子放屁的文章,今天就把我自己开发遇到的一些痛点理一理写一哈,让自己以后也能有可以翻阅的资料,本文会持续更新个人遇到的和解决掉的关于Hooks方面的问题。
一、参数变化触发数据更新
使用场景:获取Table数据等
当Table数据的页码和筛选项变化的时候,想触发获取数据的方法运行
import React, { useState, useEffect } from 'react'
export default () => {
const [page, setPage] = useState(1)
const [dataSource, setDataSource] = useState([])
funtion loadData( ) {
getdata({
page,
pageSize
}).then(res => setDataSource(res.data))
}
// useEffect方法为函数组件渲染的时候会默认触发一次,当page参数变化的时候,loadData方法也会触发一次
// useEffect的第二个参数为一个数组,可以添加多个数组对象,如[page, search]
useEffect(loadData, [page])
}
二、销毁函数组件的时候,怎么设置回调函数
使用场景:设置了定时器等方法的时候,组件销毁的时候清理定时器释放内存
import React, { useState, useEffect } from 'react'
export default () => {
const [count, setCount] = useState(0)
const timer = setInterval(() => {
setCount(count + 1)
}, 1000)
// useEffect方法的第一个参数是一个函数,函数可以return一个方法,这个方法就是在组件销毁的时候会被调用
useEffect(() => {
return () => {
clearInterval(timer)
}
}, [])
}
三、如何拿到函数组件内的ref三、如何拿到函数组件内的ref
使用场景:子组件内使用了一些输入框Input等组件的时候,想在父组件内获取子组件的Input的ref方法
import React, { useState, useEffect } from 'react'
import { Input } from 'antd'
export const Child = React.forwardRef((props, ref) => {
// 当外部传入ref时,可以通过forwardRef的第二个参数获取到ref属性的值
// ref如果有值,就赋值把控制权给父组件;若为空,则可以在子组件内部控制Input
const inputRef = ref || React.createRef()
return <>
<Input ref={inputRef} />
</>
})
export default class Father extends React.Component {
constuctor (props) {
super(props)
this.inputRef = React.createRef()
}
componentDidMount () {
// 1妙后让Child组件的Input标签聚焦
setTimeout(() => {
this.textRef.current.focus()
}, 1000)
}
render () {
// 通过ref传递inputRef参数,从而获取到Input的控制权
return <>
<Child ref={this.inputRef} />
</>
}
}
四、用函数组件制作Table列表,筛选条件让useState十分臃肿
使用场景:Table的筛选项有page、search、dateTime、order、type等等
如果给每个筛选项加一个useState来控制的话,不得不说代码会比较臃肿,难以维护且不优雅(装起来了就),下面就来解决一下这个痛点
// utils.js
import { useState } from 'react'
export default (initial, setPage) => {
const [state, setState] = useState(initial)
return [state, function (newState) {
// 每次筛选条件变化的时候,就重新设置到第一页,
setPage && setPage(1)
// 新的覆盖参数覆盖掉老的参数
setState({ ...state, ...newState })
}]
}
// index.js
import React, { useState, useEffect } from 'react'
import { Table } from 'antd'
import useMergeFilter from './utils'
export default () => {
const [dataSource, setDataSource] = useState([])
const [page, setPage] = useState(1)
const [total, setTotal] = useState(0)
const [filter, setFilter] = useMergeFilter({ keyword: undefined, status: '' }, setPage)
function loadData () {
// 将参数展开传入
getdata({ page, pageSize, ...filter }).then(res => setDataSource(res.data))
}
// 每次filter和page变化都会触发loadDate函数运行
useEffect(loadData, [filter, page])
return <>
<div className='filter'>
// 只需在回调函数里执行setFilter并传入需要的参数,就能触发列表更新
<Input.Search placeholder='搜索' onSearch={value => setFilter({ keyword: value })} />
<Select defaultValue='' onChange={value => setFilter({ status: value })}>
<Select.Option value='A'>A</Select.Option>
<Select.Option value='B'>B</Select.Option>
</Select>
</div>
<Table
columns={columns()}
dataSource={dataSource}
/>
</>
}
五、新特性函数组件结合antd的表单form组件
使用场景:函数组件内使用表单,获取form属性
这个使用场景就比较多了,正常的类组件我们都会,antd的官方也有介绍;但用函数组件写有的同学就会有点懵,form去哪里取
import React, { useState, useEffect } from 'react'
import { Form, Button } from 'antd'
// 抛出函数组件的时候,通过Form.create()方法生成的新的组件,可以通过({ form })的形式拿到整个表单的form对象
// 下面就可以随心所欲的操作form内的表单数据了
const Demo = ({ form }) => {
const handleSubmit = (e) => {
e.preventDefault()
form.validateFields((err, values) => {
console.log('err', err)
console.log('values', values)
})
}
<Form onSubmit={handleSubmit}>
<div>
<FormItem label='用户ID'>
{getFieldDecorator('id', {
initialValue: '',
})(
<Input placeholder='输入用户名id' />
)}
</FormItem>
<Form.Item>
<Button type='primary' htmlType='submit'>提交</Button>
</Form.Item>
</div>
</Form>
}
const WrappedRegistrationForm = Form.create()(Demo)
export default WrappedRegistrationForm