基于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

浙公网安备 33010602011771号