前端烂笔头专注前端开发
首页/使用React Hook新特性遇到的一些问题(持续更新)/
使用React Hook新特性遇到的一些问题(持续更新)
2019-10-01 1005

一、参数变化触发数据更新

使用场景:获取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
大胡子程序员,专注于WEB和移动前端开发

如果文章对你有帮助,可以给作者一点鼓励。这将是作者持续输出的动力.

系统由 Node + React + Ant Desgin 驱动
浙ICP备19047249号-1 邮箱地址:xianyou1993@qq.com