9.useReducer+useContext搭配使用

useReducer的缺陷

useReducer和useState一样,需要通过props在子组件中传递,很麻烦,所以可以把useReducer返回的状态和dispatch通过useContext在子组件中传递

使用方法

创建reducer

const [info, dispatch] = useReducer(mapReducer,initMap);

创建状态和dispatch的上下文

MapStateReducerContext.tsx

import React from "react";
export const MapStateContext=React.createContext<any>(null);
export const MapDispatchContext=React.createContext<any>(null);

设置状态和dispatch到上下文中

import {MapStateContext,MapDispatchContext} from './MapStateReducerContext';
    return (
        <MapStateContext.Provider value={info}>
            <MapDispatchContext.Provider value={dispatch}>
				{children}
            </MapDispatchContext.Provider>
        </MapStateContext.Provider>
    );

使用reducer

import * as action from './MapReducerAction'; //导入action
const state=useContext(MapStateContext); //获取状态上下文
const dispatch=useContext(MapDispatchContext);//获取dispatch上下文

dispatch(action.<action函数>(action参数)

案例

import React, { useReducer,useState,useContext } from 'react';
import * as action from './MapReducerAction';
import {mapReducer} from './MapReducer';
import {MapStateContext,MapDispatchContext} from './MapStateReducerContext';

const initMap = {
    name: 'px',
    info: {
        age: '18',
        address: 'beijing'
    }
}

function MapItem({ key1, value }: { key1: string; value: string}) {
    const [readOnly, setReadOnly] = useState(true);
    const [item, setItem] = useState(value);
    const dispatch=useContext(MapDispatchContext);
    function editItem() {
        if (readOnly) {
            setReadOnly(false);
        } else {
            switch(key1){
                case 'name':
                    dispatch(action.update_name(item));
                    break;
                case 'info.age':    
                    dispatch(action.update_age(item));
                    break;
                case 'info.address':
                    dispatch(action.update_address(item));
                    break;
                default:
                    console.log('error key1',key1);
                    break;
            }
            setReadOnly(true);
        }
    }
    if (readOnly) {
        return (<div>{value}<button onClick={() => editItem()}>编辑</button></div>);
    } else {
        return (
            <div>
                <input
                    type="text"
                    value={item}
                    onChange={(e) => setItem(e.target.value)}
                />
                <button onClick={() => editItem()}>保存</button>
            </div>
        );
    }
}

export function MapStateReducerContextTest() {
    const [info, dispatch] = useReducer(mapReducer,initMap);
    return (
        <MapStateContext.Provider value={info}>
            <MapDispatchContext.Provider value={dispatch}>
                <MapItem key1='name' value={info.name} ></MapItem>
                <MapItem key1='info.age' value={info.info.age} ></MapItem>
                <MapItem key1='info.address' value={info.info.address} ></MapItem>
            </MapDispatchContext.Provider>
        </MapStateContext.Provider>
    );
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值