使用React Hook新特性遇到的一些問題

前言:

市面上對怎麼使用React Hooks新特性的入門例子能夠說是汗牛充棟,我都懶得寫這些脫褲子放屁的文章,今天就把我本身開發遇到的一些痛點理一理寫一哈,讓本身之後也能有能夠翻閱的資料,本文會持續更新我的遇到的和解決掉的關於Hooks方面的問題。html

1、參數變化觸發數據更新

使用場景:獲取Table數據等react

當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])
}
複製代碼

2、銷燬函數組件的時候,怎麼設置回調函數

使用場景:設置了定時器等方法的時候,組件銷燬的時候清理定時器釋放內存bash

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)
		}
	}, [])
}
複製代碼

3、如何拿到函數組件內的ref3、如何拿到函數組件內的ref

使用場景:子組件內使用了一些輸入框Input等組件的時候,想在父組件內獲取子組件的Input的ref方法markdown

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} />
		</>
	}
}
複製代碼

4、用函數組件製做Table列表,篩選條件讓useState十分臃腫

使用場景:Table的篩選項有page、search、dateTime、order、type等等antd

若是給每一個篩選項加一個useState來控制的話,不得不說代碼會比較臃腫,難以維護且不優雅(裝起來了就),下面就來解決一下這個痛點app

// 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}
		/>
	</>
}

複製代碼

5、新特性函數組件結合antd的表單form組件函數

使用場景:函數組件內使用表單,獲取form屬性this

這個使用場景就比較多了,正常的類組件咱們都會,antd的官方也有介紹;但用函數組件寫有的同窗就會有點懵,form去哪裏取spa

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
複製代碼
相關文章
相關標籤/搜索