美文网首页
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>
        );
    }
    

    相关文章

      网友评论

          本文标题:React Context

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