Hooks 是React 16.8中的新增功能。它们容许您在不编写class的状况下使用状态和其余React功能,关于原理性东西其余大佬已经说不少了,我今天主要讲实践具体用法。javascript
做者本身写很推崇 hookshtml
官方连接传送门
经常使用api:java
const [storeCustomerBaseInfo, updateStoreCustomerBaseInfo] = useState({})
复制代码
数组第一个值是你须要更新的值,第二个值是更新该值得函数 useState() 函数运行的时候给默认值 我这里是给的空对象 具体更新栗子以下react
if (res.success) {
const { storeCustomerBaseInfo, storeUserPayInfo } = res.data
updateStoreCustomerBaseInfo(storeCustomerBaseInfo)
}
复制代码
通俗点就是 componentDidMount,componentDidUpdate、componentWillUnmount三个生命周期的合集,
复制代码
通常在这里发起异步请求🌰git
useEffect(() => {
getWebData(id)
}, [id])
const getWebData = async (id) => {
const res = await CustomerService.getCustomerDeatil(id)
if (res.success) {
const { storeCustomerBaseInfo, storeUserPayInfo } = res.data
updateStoreCustomerBaseInfo(storeCustomerBaseInfo)
}
}
复制代码
细心的同窗会发现我在函数末尾多加了个参数 这里至关于我相似于 didMount 方法,若是不加该参数,就会一直请求。 默认状况下,它在第一次渲染以后和每次更新以后运行,你可能会发现更容易认为效果发生在“渲染以后”,而不是考虑“挂载”和“更新”React保证DOM在运行‘效果’时已更新。 加参数就至关于自定义更新,好比我这里加了 id 只有当id 从新变化的时候再执行该方法github
好比定时器,发布订阅,有时候组件卸载的时候要取消这个时候该怎么办呢redux
return 一个新的函数api
useEffect(() => {
fecth()
return () => {
clearTimeOut()
}
})
复制代码
useState的替代方案。接受类型为(state,action) => newState的reducer,并返回与dispatch方法配对的当前状态。 (若是熟悉Redux,你已经知道它是如何工做的。) 用过 redux的相信对这个reducer 都不陌生 使用和redux 如出一撤数组
//actions.js
export const showMsg = 'SHOW_MSG'
export const openpoolInfo = 'OPENPOOL_INFO'
export const updateShowMsg = (data) => ({
type: showMsg,
data
})
export const updateOpenpoolInfo = (data) => ({
type: openpoolInfo,
data
})
复制代码
import {
showMsg,
openpoolInfo
} from './actions'
export const initState = {
showMsg: true,
openpoolInfo: {}
}
export const initReducer = (state, action) => {
switch (action.type) {
case showMsg:
return {
...state,
showMsg: action.data
}
case openpoolInfo:
return {
...state,
openpoolInfo: action.data
}
default:
return state
}
}
复制代码
最后连接组件bash
import React, { useEffect, useReducer } from 'react'
import { Page } from '../../components'
import { Divider, Button, message } from 'antd'
import { CustomerService } from '../../service'
import BaseInfo from './base_info'
import Edit from './edit'
import { yuan2Fen, fen2Yuan } from '../../helper'
import { updateShowMsg, updateEditTotalOpenPoolAmount, updateOpenpoolInfo } from './store/actions'
import { initState, initReducer } from './store/reducer'
const OpenPool = (props) => {
const [state, dispatch] = useReducer(initReducer, initState)
const { params: {id} } = props.match
useEffect(() => {
getOpenpoolInfo(id)
}, [id])
const getOpenpoolInfo = async (id) => {
const res = await CustomerService.getOpenpool(id)
if (res.success) {
dispatch(updateOpenpoolInfo(res.data))
}
}
const editChange = (editTotalOpenPoolAmount) => {
const { usedOpenPollAmount } = state.openpoolInfo
const showMsg = fen2Yuan(usedOpenPollAmount) - editTotalOpenPoolAmount > 0
dispatch(updateShowMsg(showMsg))
dispatch(updateEditTotalOpenPoolAmount(editTotalOpenPoolAmount))
}
const getParms = () => {
const { usedOpenPollAmount } = state.openpoolInfo
return {
customerId: id,
usedOpenPollAmount,
totalOpenPoolAmount: yuan2Fen(state.editTotalOpenPoolAmount)
}
}
const updateAmount = async () => {
const params = getParms()
const res = await CustomerService.updateOpenpool(params)
if (res.data) {
message.success('操做成功')
}
}
return (
<Page title='xxx'>
<BaseInfo {...state.openpoolInfo} />
<Divider />
<Edit
showMsg={state.showMsg}
{...state.openpoolInfo}
editTotalOpenPoolAmount={state.editTotalOpenPoolAmount}
editChange={editChange}
/>
</Page>
)
}
export default OpenPool
复制代码
其实和上面的没太大变化只要设置类型就好了,固然你也能够不设置
import { Button } from 'antd'
import * as React from "react";
const { useState } = React
const Home = () => {
const [count, setCount] = useState(0)
const [strings, setStrings] = useState<string[]>([])
return (<div>
<Button onClick={() => setCount(1)}>测试普通类型</Button>
<Button onClick={() => setStrings([])}>测试检测类型</Button>
</div>)
}
export default Home
复制代码
再来看看使用 interface
import { Button } from 'antd'
import * as React from "react";
const { useState } = React
interface IType {
counts: number;
}
const About = () => {
const [counts, setCount] = useState<IType[]>([]);
return (<div> <Button onClick={() => setCount([{counts: 1}])}>测试普通类型</Button> <Button onClick={() => setCount([]}>测试普通类型</Button> </div>)
}
export default About
复制代码
以上是我我的的实践,如今估计看完都会有疑问究竟是用 useState 仍是 useReducer, 看了国外某大神的文章你就明白了 传送门