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

NO IMAGE

前言:

市面上對怎麼使用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

相關文章

排序演化(一):希爾

Promises/A+實現,一條規範對應一段代碼

JS類型

js循環語句中的async與await