React 数据共享useContext的实现

因为疫情, 最近接手一个新项目。是React的。上次写React已经过去1年多了。

虽然捡起来也不是什么难事,不过技术这个东西,长时间不用就容易忘记。

为了保证这个项目根其他平行项目的技术栈统一。

采用的是 Nextjs 、styled-components、useContext 、react-query、ts

今天不做重点介绍项目,还是说说在项目中碰到的问题。

这个足足折腾了差不多2个小时,我一直在排查其问题。

最后这个问题也是比较的诡异。

ReferenceError: Cannot access 'Context' before initialization This error happened while generating the page. Any console logs will be displayed in the terminal window.

引用错误 , 不能在初始化之前访问Context , 在生成页面的时候就已经发生。在Shell控制台也有显示输出。

我尝试过很多的办法, 例如:换用引用的方式、多个Provider的位置调整,甚至只保留一个 , 依然无法解决。

后来我试试可能组建声明的类型问题。

我平时对于写组建的方式比较随意。

最喜欢的一种方式就是

import { useState  , createContext} from 'react'
import Me from './me'
export const MyContext =  createContext({});
export default function Demo(){
  const [say , setSay] = useState('');
  return (
    <MyContext.Provider value={{say , setSay}}>
      <div>father</div>谁在讲话 {say}
      <Me />
    </FatherContext.Provider>
  )
}

React.FC是函数式组件写法,是在TypeScript使用的一个泛型,FC就是FunctionComponent的缩写,事实上React.FC可以写成React.FunctionComponent ( 我对这种写法感觉太过于冗余 )

import React, { createContext, FunctionComponent, useState } from 'react'
import Me from './me'
interface DemoProps {
  say: string;
  setSay: React.Dispatch<React.SetStateAction<boolean>>;
  demoString?:string;
}
const defaultDemoProps: DemoProps = {
	isDay: true,
	setIsDay: (day) => day
};
export const MyContext = createContext<DemoProps>({...defaultDemoProps});
const Demo: React.FC<DemoProps> = ({ children, ...props }) => {
  const { say : propIsSay } = props;
  const [ isSay, setSay ] = useState(propIsDay)
  return <MyContext.Provider value={{ say,setSay}}>
      <Me />
    </MyContext.Provider>
}
export default Demo;

还有很多习惯使用class components

import React, { createContext, PureComponent } from 'react'
import Me from './me'
export const MyContext = createContext({})
export default class Demo extends PureComponent {
  state = {
    say:true,
  }
  setSay ()=>{
    let say = !this.state.say
    this.setState({
      say
    });
  }
  render() {
    return(
      <MyContext.Provider value={{ say,setSay}}>
      <Me />
      <MyContext.Provider>
    )
  }
}

这是三种的构造方式

createContext 函数返回的有3个属性分别是 Provider ( 提供者 )、Customer( 消费者 )、displayName ( 貌似用不到 )

import React, { Context, PureComponent } from 'react';
import {MyContext} from '../components/data';
import Memo from '../components/classDemo';
export const MyContext = React.createContext()
export default class CurstomerDemo extends PureComponent {
  static contextType = MyContext  // 重点是这句 用来指定
	constructor(props) {
		super(props);
	}
  handleClick = () => {
    console.log (this.context) // 获取上下文 Provider 属性
  }
	render() {
		return (
      <div>
        <button>Provider</button>
        <button onClick={this.handleClick}>Customer</button>
      </div>
		)
	}
}

import React, { useState  ,useContext, createContext} from 'react'
import {MyContext} from './Demo'
function useCountContext(CounterContext) {
  const context = useContext(MyContext) //重点这句话,用来获取指定的上线文Context
  if (!context) {
    throw new Error('useCountContext must used within Context.Provider')
  }
  return context
}
export default function Me(props){
  let context = useCountContext(MyContext)
  let {say , setSay} = context
  return (
    <div>
      me
      <button onClick={()=>{
        setSay(say + ',同志们好')
      }}>come from grandpa Provier {say}</button>
    </div>
  )
}

其实关键的还是用函数方式来接受函数的Provider , 类组件来接受类组件的Provider。保证构造的一致。

PS:useContext 我个人觉得对于小型项目还是非常的不错,但是对于复杂的数据,他的分层意识还是不够清晰。thunksagamobx 都在一定程度上在分层上更适合context。当然你也可以对context更进一步封装。适合自己的才是最好!

到此这篇关于React 数据共享useContext的实现的文章就介绍到这了,更多相关React 数据共享useContext内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • React学习之受控组件与数据共享实例分析

    本文实例讲述了React学习之受控组件与数据共享.分享给大家供大家参考,具体如下: 在HTML当中,像<input>,<textarea>, 和 <select>这类表单元素会自己储存值,并且根据用户输入进行更新.但在React中,可变的值通常保存在组件的state中,并且只能用 setState() 方法进行更新.为了解决二者的矛盾,可以让HTML元素不再自己储存数据,而使用来自于react的state.也就是说HTML元素把数据保存在react组件的state中,并

  • 用react-redux实现react组件之间数据共享的方法

    上篇文章写到了redux实现组件数据共享的方法,但是在react中,redux作者提供了一个更优雅简便的模块实现react组件之间数据共享.那就是利用react-redux 利用react-redux实现react组件数据之间数据共享 1.安装react-redux $ npm i --save react-redux 2.从react-redux导入Prodiver组件将store赋予Provider的store属性, 将根组件用Provider包裹起来. import {Provider,c

  • React 数据共享useContext的实现

    因为疫情, 最近接手一个新项目.是React的.上次写React已经过去1年多了. 虽然捡起来也不是什么难事,不过技术这个东西,长时间不用就容易忘记. 为了保证这个项目根其他平行项目的技术栈统一. 采用的是 Nextjs .styled-components.useContext .react-query.ts 今天不做重点介绍项目,还是说说在项目中碰到的问题. 这个足足折腾了差不多2个小时,我一直在排查其问题. 最后这个问题也是比较的诡异. ReferenceError: Cannot acc

  • React函数组件useContext useReducer自定义hooks

    目录 一.hooks(useContext) 二.hooks(useReducer) 三.hooks(useContext搭配useReducer使用) 四.自定义hooks 一.hooks(useContext) 接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值.当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定. 新建useContext.js

  • React 中的 useContext使用方法

    目录 什么是上下文呢? useContext使用的方法: 1.要先创建createContex 2.Provider 指定使用的范围 3.最后使用useContext useContext就是上下文 什么是上下文呢? 全局变量就是全局的上下文,全局都可以访问到它:上下文就是你运行一段代码,所要知道的所有变量 useContext使用的方法: 1.要先创建createContex 使用createContext创建并初始化 const C = createContext(null); 2.Prov

  • React Hook的使用示例

    这篇文章分享两个使用React Hook以及函数式组件开发的简单示例. 一个简单的组件案例 Button组件应该算是最简单的常用基础组件了吧.我们开发组件的时候期望它的基础样式能有一定程度的变化,这样就可以适用于不同场景了.第二点是我在之前做项目的时候写一个函数组件,但这个函数组件会写的很死板,也就是上面没有办法再绑定基本方法.即我只能写入我已有的方法,或者特性.希望编写Button组件,即使没有写onClick方法,我也希望能够使用那些自带的默认基本方法. 对于第一点,我们针对不同的class

  • React中10种Hook的使用介绍

    目录 React Hook是什么? React目前提供的Hook 1.useState 2.useEffect & useLayoutEffect 3.useMemo & useCallback 4.useRef 5.useContext 6.useReducer React Hook是什么? React官网是这么介绍的: Hook 是 React 16.8 的新增特性.它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性. 完全可选的 你无需重写任何已有

  • React封装CustomSelect组件思路详解

    目录 思路和前提 编码与实现 处理createContext与useContext 对content的封装和拆分: DispatchRender, Controls 先说Controls, 包含控制行: 重置, 确定 DispatchRender 用于根据type分发对应的render子组件,这是一种编程思想,在次可以保证父子很大程度的解耦,再往下子组件不再考虑type是什么,父组件不需要考虑子组件有什么. 单选框的render子组件的具体实现 由来: 需要封装一个通过Popover弹出框里可以

  • React+Mobx基本使用、模块化操作

    目录 Mobx介绍 1.什么是Mobx 2.Mobx有什么优势 3.社区评价 浏览器支持 基础使用 1. 初始化mobx 2. React使用store Mobx - computed Mobx - 模块化 实现步骤 代码实现 Mobx - 总结 Mobx介绍 1.什么是Mobx 一个可以和React良好配合的集中状态管理工具,和Redux解决的问题相似,都可以独立组件进行集中状态管理 mobx与react的关系,相当于vuex与vue的关系. 同类工具还有:redux.dva.recoil 2

  • React Hooks - useContetx和useReducer的使用实例详解

    目录 useContetx的使用 useReducer的使用 useContetx的使用 在之前的开发中,我们要在组件中使用共享的Context有两种方式: 类组件可以通过 类名.contextType = MyContext 的方式,在类中获取context; 多个Context或者在函数式组件中通过 MyContext.Consumer 方式共享context; 但是多个Context共享时的方式会存在大量的嵌套(会导致代码阅读性非常差): Context Hook允许我们通过Hook来直接

  • React-Route6实现keep-alive效果

    目录 一.基于react-route6  useOutlet实现 二.代码呈现 代码分析 isKeepPath useKeepOutlets location element useContext<any>(KeepAliveContext) isKeep Object.entries key hidden matchPath(location.pathname, pathname)} KeepAliveLayout FC keepElements dropByCacheKey other P

随机推荐