hooks的useReducer配合useContext实现跨组件共享通信
日期:2019-10-28
来源:程序思维浏览:4223次
当我们使用redux进行数据管理的时候,一般都是在根组件通过Provider的方式引入store,然后在每个子组件中,通过connect的方式使用高阶组件进行连接,这样造成的一个问题是,大量的高阶组件代码冗余度特别高,既然hooks带来了新特性,不如一起来用用看看。
先了解一下React.CreateContext,组件通信需要了解这个方法:
// 创建上下文
let {Provider, Consumer} = React.createContext()
// 假设我们有很多个组件,我们只需要在父组件使用Provider提供数据,然后我们就可以在子组件任何位置使用Consumer拿到数据,不存在跨组件的问题
// 提供数据
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
let {Provider, Consumer} = React.createContext()
// 父组件
function Parent (props) {
return (
<div>
<div>Parent: </div>
<Son></Son>
</div>
)
}
// 子组件
function Son (props) {
return (
<div>
<div>Son: </div>
<Child></Child>
</div>
)
}
// 孙子组件
function Child (props) {
return (
<Consumer>
{value => <div>
value: {value}
</div>}
</Consumer>
)
}
//使用Provider提供数据
ReactDOM.render(<Provider value="1">
<Parent />
</Provider>, document.getElementById('root'));
了解React.CreateContext后,下面看看useReducer和useContext怎么实现跨组件通信吧?
pages/reducer.js页面代码:
import React,{useReducer} from 'react';
import {counterReducer,defaultState} from '../../hooksReducer/counterReducer';
import {ReactContext} from '../../context';
import ReducerComponent from './reducerComponent';
let iCount=0;
export default function HooksReducer() {
const [state,dispatch]=useReducer(counterReducer,defaultState);
// console.log(state);
return (
<div>
<ReactContext.Provider value={{state,dispatch}}>
<ReducerComponent></ReducerComponent>
</ReactContext.Provider>
计数器: <button type="button" onClick={()=>{dispatch({type:"dec",data:{count:--iCount}})}}>-</button>{state.count}<button type="button" onClick={()=>{dispatch({type:"inc",data:{count:++iCount}})}}>+</button>
</div>
)
}
context/index.js页面代码:
import React from "react";
// 创建上下文,解决多个组件共享传值,不存在跨组件的问题
export const ReactContext = React.createContext();
hooksReducer/counterReducer.js页面代码:
export const defaultState={
count:0
};
export const counterReducer=(state=defaultState,action)=>{
switch (action.type) {
case "dec":
return {...state,...action.data};
case "inc":
return {...state,...action.data};
default:
return state;
}
};
子组件pages/reducerComponent.js页面代码:
import React,{useContext} from 'react';
import {ReactContext} from "../../context";
export default function ReducerComponent() {
//useContext:共享状态钩子
const counterContext=useContext(ReactContext);
// console.log(counterContext);
return (
<div>
子组件计数器:<button type="button" onClick={()=>{counterContext.dispatch({type:"dec",data:{count:--counterContext.state.count}})}}>-</button>{counterContext.state.count} <button type="button" onClick={()=>{counterContext.dispatch({type:"inc",data:{count:++counterContext.state.count}})}}>+</button>
</div>
)
}
hooks代码示例下载
先了解一下React.CreateContext,组件通信需要了解这个方法:
// 创建上下文
let {Provider, Consumer} = React.createContext()
// 假设我们有很多个组件,我们只需要在父组件使用Provider提供数据,然后我们就可以在子组件任何位置使用Consumer拿到数据,不存在跨组件的问题
// 提供数据
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
let {Provider, Consumer} = React.createContext()
// 父组件
function Parent (props) {
return (
<div>
<div>Parent: </div>
<Son></Son>
</div>
)
}
// 子组件
function Son (props) {
return (
<div>
<div>Son: </div>
<Child></Child>
</div>
)
}
// 孙子组件
function Child (props) {
return (
<Consumer>
{value => <div>
value: {value}
</div>}
</Consumer>
)
}
//使用Provider提供数据
ReactDOM.render(<Provider value="1">
<Parent />
</Provider>, document.getElementById('root'));
了解React.CreateContext后,下面看看useReducer和useContext怎么实现跨组件通信吧?
pages/reducer.js页面代码:
import React,{useReducer} from 'react';
import {counterReducer,defaultState} from '../../hooksReducer/counterReducer';
import {ReactContext} from '../../context';
import ReducerComponent from './reducerComponent';
let iCount=0;
export default function HooksReducer() {
const [state,dispatch]=useReducer(counterReducer,defaultState);
// console.log(state);
return (
<div>
<ReactContext.Provider value={{state,dispatch}}>
<ReducerComponent></ReducerComponent>
</ReactContext.Provider>
计数器: <button type="button" onClick={()=>{dispatch({type:"dec",data:{count:--iCount}})}}>-</button>{state.count}<button type="button" onClick={()=>{dispatch({type:"inc",data:{count:++iCount}})}}>+</button>
</div>
)
}
context/index.js页面代码:
import React from "react";
// 创建上下文,解决多个组件共享传值,不存在跨组件的问题
export const ReactContext = React.createContext();
hooksReducer/counterReducer.js页面代码:
export const defaultState={
count:0
};
export const counterReducer=(state=defaultState,action)=>{
switch (action.type) {
case "dec":
return {...state,...action.data};
case "inc":
return {...state,...action.data};
default:
return state;
}
};
子组件pages/reducerComponent.js页面代码:
import React,{useContext} from 'react';
import {ReactContext} from "../../context";
export default function ReducerComponent() {
//useContext:共享状态钩子
const counterContext=useContext(ReactContext);
// console.log(counterContext);
return (
<div>
子组件计数器:<button type="button" onClick={()=>{counterContext.dispatch({type:"dec",data:{count:--counterContext.state.count}})}}>-</button>{counterContext.state.count} <button type="button" onClick={()=>{counterContext.dispatch({type:"inc",data:{count:++counterContext.state.count}})}}>+</button>
</div>
)
}
hooks代码示例下载
- 上一篇:二维码原理简单易懂
- 下一篇:前端面试必须要了解的HTTP的3次握手和4次挥手
精品好课