React Hooks —— useContext上下文通信

useContext

为了实现祖孙组件的便捷通信,不使用繁琐的props和ref层层传递信息,可以使用Hooks组件的context特性实现通信请添加图片描述

步骤

  1. 根目录下使用createContext创建一个上下文对象,用来管理上下文中的信息

    src/ThemeContext.js

    // 创建上下文对象
    import { createContext } from 'react';
    const ThemeContext = createContext();
    export default ThemeContext;
    
  2. 让祖先组件具备状态和修改状态的方法。将所有后代组件包裹到上下文对象.Provider中,通过value对象存储上下文中共享的数据和方法,祖先组件更新时会往上下文中放入最新的共享内容

  3. 在后代组件中使用useContext解构上下文对象获取上下文信息。

注意:

上下文操作的核心是上下文对象,如ThemeContext。创建多个不同的上下文对象,可以基于不同上下文对象中的Provider存放不同的上下文信息,同时也可以基于不同的上下文对象,获取指定上下文中的信息

在子组件Main和Footer中获取父组件属性和方法

import React, { useContext, useMemo, useState } from 'react'
import { PropTypes } from 'prop-types';
import { Button } from 'antd';
// 3.导入上下文对象
import ThemeContext from 'src/ThemeContext';
export default function ContextCommunication() {
  // 2.祖先组件具备状态和修改状态的方法
  const [supNum, setSupNum] = useState(0);
  const [oppNum, setOppNum] = useState(0);
  const changeHandler = (type) => {
    return () => {
      switch (type) {
        case 'sup':
          setSupNum(supNum + 1);
          break;
        case 'opp':
          setOppNum(oppNum + 1);
          break;
        default:
          break;
      }
    }
  }
  // 4.将所有后代组件包裹到上下文对象的Provider中,通过value对象存储上下文中共享的数据和方法
  // 祖先组件更新时会往上下文中放入最新的共享内容
  return <ThemeContext.Provider value={{
    supNum,
    oppNum,
    changeHandler
  }}>
    <div className='vote'>
      <div className="header"></div>
      <Main />
      <Footer />
    </div>
  </ThemeContext.Provider>
}
const Main = () => {
  // 5.解构useContext(context对象)返回值
  const { supNum, oppNum } = useContext(ThemeContext);
  // 数据缓存,类似vue计算属性
  const totalNum = useMemo(() => {
    return supNum + oppNum;
  }, [supNum, oppNum])
  return <div className='vote-main'>
    <ul>
      <li>支持人数:<span>{supNum}</span></li>
      <li>反对人数:<span>{oppNum}</span></li>
      <li>支持比率:<span>{totalNum ? (supNum / totalNum * 100).toFixed(2) + '%' : '--'}</span></li>
    </ul> 
  </div>
}
const Footer = () => {
  const { changeHandler } = useContext(ThemeContext)
  return <div className='vote-footer'>
    {/* 传参一:高阶函数 currying */}
    <Button onClick={changeHandler('sup')} type='primary'>支持</Button>
    <Button onClick={changeHandler('opp')} type='warn'>反对</Button>

    {/* 传参二:非高阶 合成函数 回调 */}
    {/* 传参三:bind
        <button onClick={change.bind(null, 'sup')}>支持</button>
        <button onClick={change.bind(null, 'opp')}>反对</button>
    */}
  </div>
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值