React中Context:context和provider的关系;createContext传参和Provider传参有优先级吗

最近在自学React,学到了它的一个集中状态管理工具Mobx。在使用Mobx进行数据传递的过程中,对Store进行模块化时,用到了React的context 这个API,用于导出统一的useStore方法给业务组件使用。

前引

Mobx中使用context进行模块统一导出,代码如下:

1. 定义task模块

//store/taskStore.js
import { makeAutoObservable } from 'mobx'

class TaskStore {
  taskList = []
  constructor() {
    makeAutoObservable(this)
  }
  addTask () {
    this.taskList.push('vue', 'react')
  }
}

const task = new TaskStore()
export default task

2. 定义counterStore

//store/counterStore.js
import { makeAutoObservable } from 'mobx'

class CounterStore {
  count = 0
  list = [1, 2, 3, 4, 5, 6]
  constructor() {
    makeAutoObservable(this)
  }
  addCount = () => {
    this.count++
  }
  changeList = () => {
    this.list.push(7, 8, 9)
  }
  get filterList () {
    return this.list.filter(item => item > 4)
  }
}

const counter = new CounterStore()
export default counter

3. 组合模块导出统一方法 

//store/index.js
import React from 'react'

import counter from './counterStore'
import task from './taskStore'

class RootStore {
  constructor() {
    this.counterStore = counter
    this.taskStore = task
  }
}
//实例化操作
const rootStore = new RootStore()
//使用React context机制 完成统一封装  Provider value = {传递的数据} 

// context机制的数据查找链  Provider如果找不到 就找createContext方法执行时传入的参数
const context = React.createContext(rootStore)
//通过useContext拿到rootStore实例对象,然后返回 
//只要在业务组件中,调用useStore() -> rootStore
const useStore = () => React.useContext(context)
// useStore() =>  rootStore  { counterStore, taskStore }

export { useStore }

4. 组件使用模块中的数据

//app.jsx
import { observer } from 'mobx-react-lite'
// 导入方法
import { useStore } from './store'
function App() {
  // 得到store
  const store = useStore()
  return (
    <div className="App">
      <button onClick={() => store.counterStore.addCount()}>
        {store.counterStore.count}
      </button>
    </div>
  )
}
// 包裹组件让视图响应数据变化
export default observer(App)

React中的context和provider是什么

在React中,Context是一种用于在组件树中共享数据的机制。它允许您在组件之间传递数据,而无需通过props手动传递。

Context由两个主要部分组成:

  • Context对象:通过调用React.createContext()创建。这个函数返回一个Context对象,它包含了Provider和Consumer两个属性。Context对象用于定义共享数据的结构和默认值。
  • Provider组件:Provider是Context对象的一个组件,用于向下层组件传递共享数据。它通过value属性接收数据,并将其传递给下层的Consumer组件。

使用Context,可以避免在组件层级中手动传递数据,特别是对于需要在多个组件之间共享的全局数据非常有用。它提供了一种在组件树中传递数据的方式,使得子组件可以轻松地访问共享数据。

为什么不用props而用context

通常来说,通过 props 将信息从父组件传递到子组件。但是:

  1. 如果必须通过许多中间组件向下传递 props
  2. 或在应用中的许多组件需要相同的信息

传递 props 会变的十分冗长和不便。Context 允许父组件向其下层无论多深的任何组件提供信息,而无需通过 props 显式传递。

Context传参和Provider传参的关系

context传参包含了provider传参。在React中,Context是这样传递参数的:

  • 通过Provider传递参数

在使用Context时,可以在Context.Provider组件上的value属性来传递参数。这个参数可以是任何的javascript对象,数组,函数等。

//创建了一个名为`MyContext`的Context对象
//1. 通过createContext传入默认值
const MyContext = React.createContext('defalut value');

function App() {
  const data = "Hello, Context!";

  return (
//2. 通过context对象的provider value将data作为参数传入
    <MyContext.Provider value={data}>
      <ChildComponent />
    </MyContext.Provider>
  );
}
  • 通过Consumer或useConetxt接收参数

使用Context.Consumer组件或useContext钩子可以在组件中接收Context提供的参数。

const MyContext = React.createContext();

function ChildComponent() {
  return (
    <MyContext.Consumer>
      {value => <div>{value}</div>}
    </MyContext.Consumer>
  );
}

//或者使用useContext钩子:

const MyContext = React.createContext();

function ChildComponent() {
  const value = useContext(MyContext);

  return <div>{value}</div>;
}
//在ChildComponent组件中使用Context.Consumer组件或useContext钩子来接收Context提供的参数

useContext接收的参数有哪些,哪个优先级高

当使用Provider组件提供参数时,通过value属性传递的数据会成为当前组件及其所有子组件中可用的共享数据。

当使用useContext钩子来接收参数时,它会查找最近的上层Provider组件,并返回该Provider组件提供的值。

总之,优先级是根据组件树的结构来确定的。如果在组件树中有多个Provider组件,useContext钩子将返回最近的上层Provider组件提供的值。如果没有找到任何Provider组件,useContext将返回Context对象的默认值(在createContext时指定的默认值)。

import React,{ useContext } from 'react'
//通过createContext传入默认值
const MyContext = React.createContext('Default Value')
function App() {
  const valueFromProvider = 'Value from Provider'

  return (
//通过Provider value传参
    <MyContext.Provider value={valueFromProvider}>
      <ChildComponent />
    </MyContext.Provider>
  )
}

function ChildComponent() {
// context机制的数据查找链  Provider如果找不到 就找createContext方法执行时传入的参数
  const valueFromContext = useContext(MyContext)

  return (
    <div>
      <div>Value from Provider: {valueFromContext}</div>
    </div>
  )
}
export default App

//页面最终展示为Value from Provider:Value from Provider 

初学小白,以上仅个人拙见,望不吝赐教

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值