react-15-React.createContext() 与 useReducer()

110 阅读2分钟

一、React.createContext()

提供者

GlobalContext.Provider 提供value作为后代组件所需的状态和方法

import React, { useState } from "react"
import Child1 from "./components/Child1"
import Child2 from "./components/Child2"
import Child3 from "./components/Child3"
export const GlobalContext = React.createContext()
const App = () => {
  const [name, setname] = useState("zrs")
  return (
    <GlobalContext.Provider
      value={{
        name,
        changName: (name) => {
          setname(name)
        }
      }}
    >
      <Child1></Child1>
      <Child3></Child3>
      <Child2></Child2>
    </GlobalContext.Provider>
  )
}
export default App

消费者书写方式一:<GlobalContext.Consumer>

这种方式需要在 GlobalContext.Consumer 里面书写一个函数,该函数中value就是GlobalContext.Provider中的value

import React from "react"
import { GlobalContext } from "../App"
const Child3 = () => {
  return (
    <GlobalContext.Consumer>
      {(value) => {
        return <div>Child3---- {value.name}</div>
      }}
    </GlobalContext.Consumer>
  )
}
export default Child3

消费者书写方式二:useContext()

直接将GlobalContext 作为参数给 useContext ,就可获得对应value

import React, { useContext } from "react"
import { GlobalContext } from "../App"
const Child1 = () => {
  const { name } = useContext(GlobalContext)
  return <div>Child1===={name}</div>
}
export default Child1
import React, { useContext } from "react"
import { GlobalContext } from "../App"
const Child2 = () => {
  const { changName } = useContext(GlobalContext)
  return (
    <div>
      Child2
      <hr />
      <button
        onClick={() => {
          changName("小张")
        }}
      >
        changName
      </button>
    </div>
  )
}
export default Child2

二、useReducer()与 React.createContext()

React.createContext() 提供了跨级组件通信的办法。

useReducer() 可以简化局部区域的组件状态管理。类似于redux的核心模块。

父组件

useReduce() 接收两个参数,

第一个是一个函数,也就是代码中的reducer

第二个是一个对象,这个对象装着一些状态就是代码中的initialState

通过该函数可以解构出两个东西,一个是代码中的state,一个修改状态的dispatch

React.createContext()

API返回一个提供者组件,配合useContext实现跨级通信。

GlobalContext.Provider 有一个value属性,将需要跨级通信的东西写在里面。

import React, { useReducer } from "react"
import Child1 from "./components/Child1"
import Child2 from "./components/Child2"
import Child3 from "./components/Child3"

const initialState = {
  name: "zrs",
  password: "123456789"
}

const reducer = (prevState, action) => {
  console.log(prevState, action)
  let newState = { ...prevState }
  switch (action.type) {
    case "change-name":
      newState.name = action.value
      return newState
    case "change-pwd":
      newState.password = action.value
      return newState

    default:
      return prevState
  }
}
export const GlobalContext = React.createContext()

const App = () => {
  const [state, dispatch] = useReducer(reducer, initialState)
  return (
    <GlobalContext.Provider
      value={{
        state,
        dispatch
      }}
    >
      <Child1 />
      <Child2 />
      <Child3 />
    </GlobalContext.Provider>
  )
}

export default App

子组件Child1

子组件中引入 GlobalContext 使用useContext() 获取GlobalContext.Provider 提供value里面的值

import React, { useContext } from "react"
import { GlobalContext } from "../App"
const Child1 = () => {
  const { state } = useContext(GlobalContext)
  return <div>Child1---{state.name}</div>
}

export default Child1

子组件Child2

子组件中引入 GlobalContext 使用useContext() 获取GlobalContext.Provider 提供value里面的值

import React, { useContext } from "react"
import { GlobalContext } from "../App"
const Child2 = () => {
  const { state } = useContext(GlobalContext)
  return <div>Child2---{state.password}</div>
}

export default Child2

子组件Child3

import React, { useContext } from "react"
import { GlobalContext } from "../App"
const Child3 = () => {
  const { dispatch } = useContext(GlobalContext)
  return (
    <div>
      <hr />
      <button
        onClick={() => {
          dispatch({ type: "change-name", value: "名字被修改了" })
        }}
      >
        chang-name
      </button>
      <hr />
      <button
        onClick={() => {
          dispatch({ type: "change-pwd", value: "密码被修改了" })
        }}
      >
        chang-pwd
      </button>
    </div>
  )
}

export default Child3