美文网首页
React Context

React Context

作者: Suki_Yang | 来源:发表于2020-12-15 10:44 被阅读0次

Context

Context provides a way to pass data through the component tree without having to pass props down manually at every level.

API

React.createContext
const MyContext = React.createContext(defaultValue);
Context.Provider
<MyContext.Provider value={/* some value */}>
Class.contextType
class MyClass extends React.Component {
    componentDidMount() {
        let value = this.context;
    }
    componentDidUpdate() {
        let value = this.context;
    }
    componentWillUnmount() {
        let value = this.context;
    }
    render() {
        let value = this.context;
    }
}
//The contextType property on a class can be assigned a Context object created by React.createContext()
MyClass.contextType = MyContext;
Context.Consumer
<MyContext.Consumer>
    {value => /* render something based on the context value */}
</MyContext.Consumer>

The function receives the current context value and returns a React node.

Context.displayName

Context object accepts a displayName string property. React DevTools uses this string to determine what to display for the context.

const MyContext = React.createContext(/* some value */);
MyContext.displayName = 'MyDisplayName';

<MyContext.Provider> // "MyDisplayName.Provider" in DevTools
<MyContext.Consumer> // "MyDisplayName.Consumer" in DevTools

Example

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

class App extends React.Component {
    render() {
        return (
            <ThemeContext.Provider value="dark">
                <Toolbar />
            </ThemeContext.Provider>
        );
    }
}

function Toolbar() {
    return (
        <div>
            <ThemedButton />
        </div>
    );
}

class ThemedButton extends React.Component {
    static contextType = ThemeContext;
    render() {
        return <Button theme={this.context} />;
    }
}
Dynamic Context
//theme-context.js
export const theme = {
    light: {
        foreground: '#000000',
        background: '#eeeeee'
    },
    dark: {
        foreground: '#ffffff',
        background: '#222222'
    }
};

export const ThemeContext = React.createContext(themes.dark);
//themed-button.js
import {ThemeContext} from './theme-context';

class ThemedButton extends React.Component {
    render() {
        let props = this.props;
        let theme = this.context;
        return (
            <button
                {...props}
                style={{backgroundColor: theme.background}} 
            />
        );
    }
}
ThemedButton.contextType = ThemeContext;

export default ThemedButton;
//app.js
import {ThemeContext, themes} from './theme-context';
import ThemedButton from './themed-button';

function Toolbar(props) {
    return (
        <ThemedButton onClick={props.changeTheme}>
            Change Theme
        </ThemedButton>
    );
}

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            theme: themes.light
        };
    }
    
    this.toggleTheme = () => {
        this.setState(state => ({
            theme: state.theme === themes.dark ? themes.light : themes.dark
        }));
    };
    
    render() {
        return (
            <Page>
                <ThemeContext.Provider value={this.state.theme}>
                    <Toolbar changeTheme={this.toggleTheme}/>
                </ThemeContext.Provider>
                <section>
                    <ThemedButton />
                </section>
            </Page>
        );
    }
}

ReactDOM.render(<App />, document.root);
Updating Context from a Nested Component
//theme-context.js
export const ThemeContext = React.createContext({
   theme: themes.dark,
   toggleTheme: () => {}
});
//theme-toggler-button.js
import {ThemeContext} from './theme-context';

function ThemeTogglerButton() {
    return (
        <ThemeContext.Consumer>
            {({theme, toggleTheme}) => (
                <button
                    onClick={toggleTheme}
                    style={{backgroundColor: theme.background}}
                >
                    Toggle Theme
                </button>
            )}
        </ThemeContext.Consumer>
    );
}

export default ThemeTogglerButton;
//app.js
import {ThemeContext, themes} from './theme-context';
import ThemeTogglerButton from './theme-toggler-button';

class App extends React.Component {
    constructor(props) {
        super(props);
        
        this.toggleTheme = () => {
            this.setState(state => ({
                theme: state.theme === themes.dark ? themes.light : themes.dark
            }));
        }
        
        this.state = {
            theme: themes.light,
            toggleTheme: this.toggleTheme
        };
        
        render() {
            return (
                <ThemeContext.Provider value={this.state}>
                    <Content />
                </ThemeContext.Provider>
            );
        }
    }
}

function Content() {
    return (
        <div>
            <ThemeTogglerButton />
        </div>
    );
}

ReactDOM.render(<App />, document.root);
Consuming Multiple Contexts

To keep context re-rendering fast, React needs to make each context consumer a separate node in the tree.

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

const UserContext = React.createContext({name: 'Guest'});

class App extends React.Component {
    render() {
        const {signedInUser, theme} = this.props;
        
        return (
            <ThemeContext.Provider value={theme}>
                <UserContext.Provider value={signedInUser}>
                    <Layout />
                </UserContext.Provider>
            </ThemeContext.Provider>
        );
    }
}

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

function Content() {
    return (
        <ThemeContext.Consumer>
            {theme => (
                <UserContext.Consumer>
                    {user => (
                        <ProfilePage user={user} theme={theme} />
                    )}
                </UserContext.Consumer>
            )}
        </ThemeContext.Consumer>
    );
}

相关文章

  • 2018-08-08

    React 高级指南 React 新版上下文(context) context ?答:上下文(Context) 提...

  • React中不常用的功能——Context

    React中不常用的功能——Context Context React源码版本16.8 基本用法 跨层级通信 Co...

  • 疑问汇总

    1. react context是怎样实现 跨组件通信的? 从Context源码实现谈React性能优化[http...

  • react context

    react context React.createContext, Provider(数据提供者), Consu...

  • React 拾遗之 Context

    React 拾遗之 Context React.js 的 context 其实像就是组件树上某颗子树的全局变量 使...

  • react-redux源码解读

    "react-redux": "^5.0.6" redux和react之间的桥梁是react的context,re...

  • React-深入探究Context(1)

    前言 React组件中的Context与Android中的Context类似,都可以理解为上下文。而React中的...

  • react 笔记

    react 基本概念解析 react 的组件声明周期 react 高阶组件,context, redux 等高级...

  • React context

    Contexts 是React的一个重要属性,但是到目前为止,这个属性在正式的文档里面还没有对它进行正式介绍,在 ...

  • 【React】Context

    介绍 Contexts 是React的一个重要属性,但是到目前为止,这个属性在正式的文档里面还没有对它进行正式介绍...

网友评论

      本文标题:React Context

      本文链接:https://www.haomeiwen.com/subject/vunigktx.html