上下文(Context)

从上级而下一层一层的传递

function Toolbar(props){
    console.log('props',props);
    return (
        <div>
            <ThemeButton theme={props.theme}/>
        </div>
    )
}
function Button(props){
    return  <div>
                {props.theme}
            </div>
}

class ThemeButton extends Component{
    render(){
        console.log('this.props.theme',this.props.theme);
        return <Button theme={this.props.theme}>Button</Button>
    }
}

使用Context

const ThemeContext = React.createContext('light');
function Toolbar(){
    return(
        <ThemeButton/>
    )
}
function Text(props){
    return  <h2>
                { props.theme}
            </h2>
}

class ThemeButton extends Component{
    static contextType = ThemeContext;
    render(){
        return(
            <Text theme={this.context}/>
        )
    }
}
class Contexts extends Component{
    render(){
        return(
            <ThemeContext.Provider value="dark">
                <Toolbar/>
            </ThemeContext.Provider>
        )
    }
}
const ThemeContext = React.createContext('light');
<ThemeContext.Provider value='dark'>
		
</ThemeContext.Provider>
static contextType = ThemeContext;

API
React.createContext

const MyContext = React.createContext(defaultValue);

创建一个Context对象对。当React渲染订阅这个context对象的组件时,它将从组件树中匹配最接近的Provider中读取当前的context。

defaultValue参数仅当consumer(使用者)在树中没有匹配的Provider(提供者)时使用它,这有利于在不封装它们的情况下对组件进行测试。
注意:
将undefined作为Provider(提供者)值传递不会导致consumer(使用者)组件使用defaultValue。
Context.Provider

<MyContext.Provider value={/*some value*/}/>

每个Context对象都附带一个Provider React组件,允许consumer(使用者)组件来订阅context的改变。
Class.contextType
可以为类上的contextType属性分配由React.createContext()创建的context对象。这允许您使用this.context使用Context类型的最近的当前值。您可以在任何生命周期中引用它,包括render函数。
Context.Consumer

<Context.Consumer>
</Context.Consumer>

一个可以订阅context变化的React组件。这允许您订阅函数式组件中的context。
示例
动态Context

/**
 * Created by mapbar_front on 2019/8/1.
 */
import React,{Component} from 'react';
// import {ThemeContext,themes} from './../../utils/utils';

const themes = {
    light: {
        background: '#f99',
    },
    dark: {
        background: '#9ff',
    }
}

const ThemeContext = React.createContext(themes.light);

function Toolbar(props){
    return (
        <ThemeButton onClick={props.changeTheme}>
            ThemeButton
        </ThemeButton>
    )
}


class ThemeButton extends Component{
    constructor(props){
        super(props);
    }
    render(){
        let props = this.props;
        console.log('props',props);
        let theme = this.context;
        return(
            <button {...props} style={{background: theme.background}}>
                btn
            </button>
        )
    }
}
ThemeButton.contextType = ThemeContext;

class Context1 extends Component{
    constructor(props){
        super(props);
        this.state = {
            theme: themes.light,
        }
    }
    toggleTheme=()=>{
        console.log('toggleTheme');
        this.setState(state=>({
            theme: state.theme === themes.dark ? themes.light: themes.dark
        }))
    }
    render(){
        return(
            <div>
                <ThemeContext.Provider value={this.state.theme}>
                    <Toolbar changeTheme={this.toggleTheme}/>
                </ThemeContext.Provider>
                <div>
                    <ThemeButton/>
                </div>
            </div>
        )
    }
}
export default Context1;

从嵌套组件更新Context

/**
 * Created by mapbar_front on 2019/8/1.
 */
import React,{Component} from 'react';

const themes = {
    light: {
        background: '#f99',
    },
    dark: {
        background: '#9ff',
    }
}
const ThemeContext = React.createContext({
    theme: themes.dark,
    toggleTheme: ()=>{}
})

function Content(){
    return(
        <div>
            <ThemeToggleButton/>
        </div>
    )
}
function ThemeToggleButton(){
    return(
        <ThemeContext.Consumer>
            {
                ({theme,toggleTheme})=>(
                    <button
                        onClick={ toggleTheme }
                        style={{ backgroundColor:theme.background }}
                    >
                        btn
                    </button>
                )
            }
        </ThemeContext.Consumer>
    )
}
class Context2 extends Component{
    constructor(props){
        super(props);
        this.state = {
            theme: themes.light,
            toggleTheme: this.toggleTheme,
        }
    }
    toggleTheme=()=>{
        this.setState(state=>({
            theme: state.theme === themes.dark?themes.light:themes.dark
        }))
    }
    render(){
        return(
            <div>
                <ThemeContext.Provider value={this.state}>
                    <Content />
                </ThemeContext.Provider>
            </div>
        )

    }
}
export default Context2;

使用多个context

/**
 * Created by mapbar_front on 2019/8/1.
 */
import React,{Component} from 'react';

const ThemeContext = React.createContext('light');
const UserContext = React.createContext({
    name:'xiao',
});

function SlideBar(){
    return(
        <h2>
            SlideBar
        </h2>
    )
}

function Layout(){
    return(
        <div>
            <SlideBar/>
            <Content/>
        </div>
    )
}

function ProfilePage(props){
    console.log('ProfilePage',props);
    return(
        <div>
            <p>{props.user}</p>
            <p>{props.theme}</p>
        </div>
    )
}

function Content(){
    return(
        <ThemeContext.Consumer>
            {
                theme=>(
                    <UserContext.Consumer>
                        {
                            user=>(
                                <ProfilePage user={user} theme={theme}/>
                            )
                        }
                    </UserContext.Consumer>
                )
            }
        </ThemeContext.Consumer>
    )
}
class Context3 extends Component{
    render(){
        const {signedInUser,theme} = this.props;
        return(
            <div>
                <ThemeContext.Provider value='theme'>
                    <UserContext.Provider value='signedInUser'>
                        <Layout/>
                    </UserContext.Provider>
                </ThemeContext.Provider>
            </div>
        )
    }
}
export default Context3;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值