useState和useReducer都是用来存储和更新state,useReducer
状态管理是useState
的升级版。useReducer可以在外部存储变量,实现异步操作。若要实现跨组件通信,需要结合useContext来实现
一、原理:
二、useState
(一)语法
1、格式:
const [state,setState] = useState(initState)
2、渲染
通过state获取变量值
通过setState修改变量值
(二)案例-实现加减法
import React ,{useState}from 'react'
export default function App() {
const [count,setCount] = useState(1)
return (
<div>
<button onClick={()=>{
setCount(count+1)
}}>加一</button>
<div>{count}</div>
<button onClick={()=>{
setCount(count-1)
}}>减一</button>
</div>
)
}
三、useReducer
(一)语法
1、定义外部数据和方法
数据:在数据中定义初始值数据
const initState = {//外部对象,里面是初始值
count: 0
}
方法:做逻辑处理,有两个参数
通过action接受派发的方法,结合switch来对应做逻辑处理
通过prevState获取外部初始值数据
const reduce = (prevState, action) => {//处理函数
// prevState拿到的外部对象数据
// action获取到dispatch传来的对象
}
2、引用useReducer
// 格式
const [state, dispatch] = useReducer(reduce, initState)
3、渲染
通过state.变量获取值
通过dispacth结合事件向外部派发
<button onClick={() => {
dispatch({
type: 'add'
})
}}>加一</button>
{/* 通过 state.变量来获取初始值*/}
<div>{state.count}</div>
<button onClick={() => {
dispatch({
type: "reduce"
})
}}>减一</button>
(二)案例
实现一个累加累减的功能
import React, { useReducer } from 'react'
const reduce = (prevState, action) => {//处理函数
// prevState拿到的外部对象数据
// action获取到dispatch传来的对象
let newState = { ...prevState }// 不能影响老数据,深拷贝一次
switch (action.type) {
case "reduce":
newState.count--;
return newState
case "add":
newState.count++;
return newState
default :
return prevState
}
}
const initState = {//外部对象,里面是初始值
count: 0
}
export default function App() {
// 格式
const [state, dispatch] = useReducer(reduce, initState)
return (
<div>
{/* 通过 dispatch派发事件*/}
<button onClick={() => {
dispatch({
type: 'add'
})
}}>加一</button>
{/* 通过 state.变量来获取初始值*/}
<div>{state.count}</div>
<button onClick={() => {
dispatch({
type: "reduce"
})
}}>减一</button>
</div>
)
}
四、useState和useReducer实现跨组件通信
两个实现跨组件通信都需要结合useContext来实现
(一)useState+useContext
import React, { useState, useContext } from 'react'
// 1、全局定义context对象
const GlobalContext = React.createContext()
export default function App() {
const [num, setNum] = useState(0)
return (
// 一定要为父标签,作为唯一的根标签
<GlobalContext.Provider value={
{
num: num,//传递过去的值
changeNum: (value) => {
setNum(num + 1)
}
}}>
<Sub1 />
</GlobalContext.Provider>
)
}
function Sub1() {
const value = useContext(GlobalContext)
console.log(value);
const addFn = (value) => {
value.changeNum()
}
return (
<div>
<div>生产者提供的值:{value.num}</div>
<button onClick={() => addFn(value)}>加一</button>
</div>
)
}
(二)useReducer+useContext
import React, { useReducer, useContext } from 'react'
// 1、全局定义context对象
const GlobalContext = React.createContext()
// 外部方法
const reduce = (prevState, action) => {
const newState = {...prevState}
console.log(prevState, action);
switch (action.type) {
case "add":
newState.num++
return newState
case "jian":
newState.num--
return newState
default:
return prevState
}
}
// 外部数据
const initState = {
num: 0
}
export default function App() {
const [state, dispacth] = useReducer(reduce, initState)
return (
// 一定要为父标签,作为唯一的根标签
<GlobalContext.Provider value={
{
state,//传递过去的值-对象
dispacth
}}>
<Sub1 />
</GlobalContext.Provider>
)
}
function Sub1() {
const {state,dispacth} = useContext(GlobalContext)
const addFn = (dispacth) => {
dispacth({
type: "add"
// value:"11"可以带一个变量过去
})
}
const jianFn = (dispacth) => {
dispacth({
type: "jian"
// value:"11"可以带一个变量过去
})
}
return (
<div>
<div>生产者提供的值:{state.num}</div>
<button onClick={() => addFn(dispacth)}>加一</button>
<button onClick={() => jianFn(dispacth)}>减一</button>
</div>
)
}