【React.js】之Context

在大型项目中公共信息(语言、主题) 如何传递给每个组件?

用props过于繁琐

用redux小题大做

context提供了一种比较高级的组件传值的能力

import React from 'react'

// 创建 Context 填入默认值(任何一个 js 变量)
const ThemeContext = React.createContext('light')

// 底层组件 - 函数式组件
function ThemeLink (props: any) {
    // const theme = this.context // 会报错。函数式组件没有实例,即没有 this

    // 函数式组件可以使用 Consumer
    return <ThemeContext.Consumer>
        { value => <p>link's theme is {value}</p> }
    </ThemeContext.Consumer>
}

// 底层组件 - class 组件
class ThemedButton extends React.Component {
    // 指定 contextType 读取当前的 theme context。
    // static contextType = ThemeContext // 也可以用 ThemedButton.contextType = ThemeContext
    render() {
        const theme = this.context // React 会往上找到最近的 theme Provider,然后使用它的值。
        return <div>
            <p>button's theme is {theme}</p>
        </div>
    }
}
ThemedButton.contextType = ThemeContext // 指定 contextType 读取当前的 theme context。

// 中间的组件再也不必指明往下传递 theme 了。
function Toolbar(props: any) {
    return (
        <div>
            <ThemedButton />
            <ThemeLink />
        </div>
    )
}

class App extends React.Component<{}, {
    theme?: string 
}> {
    constructor(props:any) {
        super(props)
        this.state = {
            theme: 'light'
        }
    }
    render() {
        return <ThemeContext.Provider value ={this.state.theme as string}>
            <Toolbar />
            <hr/>
            <button onClick={this.changeTheme}>change theme</button>
        </ThemeContext.Provider>
    }
    changeTheme = () => {
        this.setState({
            theme: this.state.theme === 'light' ? 'dark' : 'light'
        })
    }
}

export default App

运行结果:  

UseContext的使用

代码案例:

import React, { useContext } from "react";
const themes = {
    light: {
        foreground: '#000',
        background: '#eee',
    },
    dark: {
        foreground: '#fff',
        background: '#222'
    }
}
// 创建 Context
const ThemeContext = React.createContext(themes.light)

// 隔层传递
function ThemeButton(){
   const theme = useContext(ThemeContext)
   return <button style = {{background: theme.background, color: theme.foreground}}>
       hello world
   </button>
}

function Toolbar(){
    return <div>
        <ThemeButton></ThemeButton>
    </div>

}

function App(){
    return <ThemeContext.Provider value = {themes.dark}>
        <Toolbar></Toolbar>
    </ThemeContext.Provider>
}

export default App

代码案例:

import React, { useState, useContext } from 'react';
import './App.css';
import UseContextOne from './components/useContext'
interface IThemeProps {
  [key: string] : {color: string; background: string;}
}

const themes: IThemeProps  = {
  'light': {
    color:'#000',
    background: '#eee'
  },
  'dark': {
    color:'#fff',
    background: '#222'
  }
}
export const ThemeContextOne = React.createContext(themes.light)

function App() {
  return (
    <div className="App">
       <ThemeContextOne.Provider value = {themes.light}>
          <UseContextOne />
       </ThemeContextOne.Provider>
    </div>
  );
}

export default App;

useContext.tsx

import React, {useContext} from 'react'
import {ThemeContextOne} from "../App"

export default function Context() {
    const theme = useContext(ThemeContextOne)
    console.log(theme)
    const style = {
        background: theme.background,
        color: theme.color
    }
    return (
       <div>
           <button style = {style}>button</button>
       </div>
    )
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值