什么是React Hook
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性,以及数据状态共享。
本文仅用于学习过程中记录!!!
useState介绍
useState是react自带的一个hook函数,作用是用来声明状态变量
function Example() {
const [count, setCount] = useState(0)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => {setCount(count+1)}}>Click me</button>
</div>
)
}
useEffect介绍
useEffect代替常用生命周期函数,useEffect跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API,可以比喻为它使得函数组件拥有了“生命周期函数”。
function Example() {
const [count, setCount] = useState(0)
useEffect(() => {
console.log(`useEffect => You cliked ${count}`)
return () => {
console.log('==============')
}
}, [count])
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => {setCount(count+1)}}>Click me</button>
</div>
)
}
- 在useEffect第二个参数为空时,视图每次render都会重新执行useEffect的内容,设置为[]的时候,只有首次会被渲染,设置[count]的时候,在count发生变化才执行useEffect
- 在useEffect中第二个参数设置为[],并且return一个函数,可以实现componentWillUnmount
useContext介绍
useContext可以帮助我们跨越组件层级直接传递变量,实现共享,避免一层层的传递状态。
它对所包含的组件树提供全局共享数据的
const CountContext = createContext()
function Counter() {
let count = useContext(CountContext)
return (<h2>{count}</h2>)
}
function Example() {
const [count, setCount] = useState(0)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => {setCount(count+1)}}>Click me</button>
<CountContext.Provider value={count}>
<Counter></Counter>
</CountContext.Provider>
</div>
)
}
useReducer介绍
useReducer可以看做是对 useState 做了一层包装,让我们可以更直观的去管理状态。看下它的使用方法:
function ReducerDemo() {
const [count, dispatch] = useReducer((state, action) => {
switch(action.type) {
case 'add':
return state+1
case 'sub':
return state-1
default:
return state
}
}, 0)
return (
<div>
<h2>现在计数是:{count}</h2>
<button onClick={() => {dispatch({
type: 'add'
})}}>Increment</button>
<button onClick={() => {dispatch({
type: 'sub'
})}}>Dcrement</button>
</div>
)
}
使用useContext和useReducer实现数据管理
新建一个reducer,初始化数据、添加数据处理逻辑,通过useContext包裹组件,使得被包裹的组件可以获取数据和dispatch,共享数据为了组件树能获取数据,共享dispatch让组件树可以修改数据状态信息
import React, { createContext, useReducer } from 'react';
export const CounterContext = createContext({})
export const ADD_COUNTER = 'ADD_COUNTER'
export const DELETE_COUNTER= 'DELETE_COUNTER'
const reducer = (state, action) => {
switch(action.type) {
case ADD_COUNTER:
return action.count + 1
case DELETE_COUNTER:
return action.count - 1
default:
return state
}
}
export const Counter = props => {
const [count, dispatch] = useReducer(reducer, 0)
return (
<CounterContext.Provider value={{
count, dispatch
}}>
{props.children}
</CounterContext.Provider>
)
}
ShowData组件和ChangeData组件包裹在Counter内部,因此可以通过useContext获取到父组件的数据以及dispatch,然后通过dispatch去更新状态数据信息
import React, {useContext} from 'react'
import { Counter, CounterContext, ADD_COUNTER, DELETE_COUNTER } from './counter'
function Example() {
return (
<div>
<Counter>
<ShowData></ShowData>
<ChangeData></ChangeData>
</Counter>
</div>
)
}
function ShowData() {
const { count } = useContext(CounterContext)
return (
<div>
当前计数: {count}
</div>
)
}
function ChangeData() {
const { count, dispatch } = useContext(CounterContext)
return (
<div>
<button onClick={() => {dispatch({
type: ADD_COUNTER,
count: count
})}}>增加</button>
<button onClick={() => {
dispatch({
type: DELETE_COUNTER,
count: count
})
}}>减少</button>
</div>
)
}
export default Example
通过这些就实现了类Redux的效果以达到数据管理的目的