基于react的useContext和useReducer的使用

钩子函数使函数组件中拥有state和副作用(useEffect)。官方提供了两种state管理的hook:useState,useReducer。

1.react钩子函数  -- useContext

它是react的方法函数createContext()需要先提供数据来进行给以其他使用消费

复制代码
//store/index.js
import React,{createContext,useCallback,useState} from 'react' //export const{Provider,Consumer}=createContext() export const Context=createContext() function MyProvider({children}){ const [count,setCount] = useState(12) const changeCount = useCallback(function(type){ if(type === 'add'){ setCount(count + 1) }else{ setCount(count - 1) } },[count]) return ( <Context.Provider value={ {count,changeCount} }>{children}</Context.Provider> ) } export default MyProvider
复制代码

2.index.js实例挂载引入

复制代码
import React from 'react'
import {render} from 'react-dom'
import Store from './store'
import App from './pages'
render(
   <Store>
    <App/>
  </Store>,
document.getElementById('root')
)

//引入实例组件元素进行挂载
复制代码

分解购物车功能

复制代码
import React from 'react'
import Cart from './Cart'
import User from './User'

function App(){
   return (
   <div>
    <h2>智能采购管理系统</h2>
    <hr/>
     <Cart/>
   <hr/>
    <User/>
  </div>
)
}

export default App
复制代码

3.cart功能useContext()是接收context对象(React.createContext的返回值),并返回该context的当前值。当前的context值

是有上层组件重距离当前组件最近的<MyContext.Provider>的value prop决定。

当组件上层最近的<MyContext.Provider>更新时,该hook会触发重渲染,并使用最新传递给MyContext provider的context value值

useContext被context的提供包含。来使用

复制代码
import React ,{useContext,useState} from 'react'
//as 起别名 导入的context改成Haha名字来使用数据变量
import {Context as Haha} from '../store'
function Cart(){
  //const store = useContext(Haha)
  //debugger
  //console.log(store)
  //在函数组件中,如果要使用到Context.Provider提供的数据的时候,可以使用useContext 钩子函数来进行数据使用消费
const { count , changeCount} = useContext(Haha) //这里需要是的context函数
return (
  <div>
  <button onClick={changeCount.bind(null,'add')}>增加</button>
  <span>数量:{count}</span>
  <button onClick={changeCount.bind(null,'minus')}>减少</button>
</div>
)
}
export default Cart
复制代码

4.User.js

useReducer():在hooks中提供了的useReducer功能,可以增强reducerDemo函数提供类似Redux的功能,

引入useReuduce后,useReducer接收一个reducer函数作为参数,reducer接收两个参数

一个是state另一个是action.然后返回一个状态count和dispath,count是返回状态中的值,

而dispatch是一个可以发布事件来更新state的数据。

const [state,dispatch] = useReducer(reducer,initState);

第二个参数:初始化的state.返回值为最新的state和dispatch函数(用来触发reducer函数,计算对应的state).

官方建议:对于复杂的state操作逻辑,嵌套的state的对象,推荐使用useReducer

复制代码
import React,{useCallback,useReducer,useState} from 'react'
function reducer(state,action){
 switch (action.type){
   case 'id';
   //state.id = action.value
//return state
  return{
   ...state,
    id:action.value
}
case 'sex':
//state.id = action.value
return {
   ...state,
   sex:action.value
}
case 'birthday':
  return{
   ...state,
   birthday:action.value
}
}
}

function User(){
 //表单填写
//const [id,setId]=useState(''),
//可以使用reducer原理来实现多个数据定义管理
//useReducer函数要接收两个参数
//第一个为reducer
//第二个是initializerArg 初始化值
//[any,React.DispatchWithAction]返回一个数组,第一个值为数据对象,第二个为dispatch函数
const [data,dispatch] = useReducer(reducer,{id:'jack',name:'jack',sex:'男',birthday:'2022-01-01'})

//const submitEvt = useCallback(function(){
//  console.log(id,name,sex,birthday)
//},[id,name,sex,birthday])
const submitEvt = useCallback(function(){
 //console.log(id,name,sex,birthday)
},[])
  return(
  <div>
   <h2>用户表单</h2>
  <hr/>
  <div>
    <label>用户编码</label>
  {/*
   在没有提供一个onChange事件的情况下绑定一个value属性在表单元素(input,textarea,select)
它将被渲染为一个只读属性,如果这个元素不需要修改数据,可以使用defaultValue
或则,设置onChange事件或则是readOnly属性
*/}
{/*<input defaultValue={id}/> */}
<div value={data.id}
  onChange={function(evt){
   //在这里给id赋值
  //console.log(evt)
  //setId(evt.target.value)
//使用useReducer的dispatch来执行数据更新
 dispatch({type:'id',value:evt.target.value})
}}/>
>
</div>
<div>
<label><用户性别/label>
<select value={data.sex}
     onChange={
   evt=>{
   console.log(evt.target.value)
   //类型,参数值
   dispatch({type:'sex',value:evt.target.value})
}
}>
<option value='男'>男</option>
<option value='女' >女</option>
</select>
</div>
<div>
<label>用户生日</label>
<input type='date' value={data.birthday}
onChange={evt=>{ console.log(evt.target.value)
 dispatch({type:'birthday',value:evt.target.value})
}}/>
</div>
<div>
 <button onClick={submitEvt}>提交</button>
</div>
</div>
)
}
export default User
复制代码

useCallback的命名里的回调函数就是对象声明名,是用于对性能的优化,第二个参数是用到对数据的更新的控制。

在这个函数里去进行数据更新,是不能直接去对数据操作更新,所以只能是在闭包里使用异步set方法来修改数据

因为react的数据是单向数据。只能使用异步方法来对数据修改更新。所以set来对变量进行更新赋值

{count,changeCount}=>对象外面还绑定花括号,changeCount是方法也是数据对象

Provider是对数据的下发来使用。

2.useReducer

posted @   cc-front  阅读(905)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示