Get started with React 0x013: Context

Keywords: Javascript React Attribute

0x000 overview

ContextIs the overall situation.stateLa~~

0x001 problem

First, we need the chestnutsTopbarUsed intheme,howeverthemeMust be passed in from the outermost, so it must be passed in from the outermostApp,Re introductionTopBar,This is only passed twice, but if all components need tothemeWhat about it? Or a very deep component needstheme,Most of the components in the middle don't need tothemeWhat about it? To deliver thisthemeIt must be passed down layer by layer. It's a bit uncomfortable.

class TopBar extends React.Component {
    redder() {
        return <div>
            {this.props.theme}
        </div>
    }
}

class App extends React.Component {
    render() {
        return <div>
            <TopBar theme={this.props.theme}/>
        </div>
    }
}


ReactDom.render(
    <App theme='dark'/>,
    document.getElementById('app')
)

0x002 solution

Context can solve this problem

  • Create context

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

    React.createContext creates a context, which returns an object that can be printed out:


    It should be noted that:

    • Consumer: Consumer
    • Provider: Provider
  • Create provider

    class App extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                theme: 'dark'
            }
        }
    
        render() {
            return (
                <ThemeContext.Provider value={this.state.theme}>
                    <ThemedButton/>
                    <button onClick={() => this.handleChangeTheme()} className='btn btn-primary'> Modify theme</button>
                </ThemeContext.Provider>
            );
        }
    
        handleChangeTheme() {
            this.setState({
                theme: this.state.theme === 'light' ? 'dark' : 'light'
            })
        }
    }

    ThemeContext.Provider is a component. The value provided by the value attribute can be accessed in all consumers, provided it is wrapped in the Provider.

  • Create consumer

    class ThemedButton extends React.Component {
    
        render() {
            return <ThemeContext.Consumer>
                {
                    (value) => <div>{value}</div>
                }
            </ThemeContext.Consumer>
        }
    }

    ThemeContext.consumer is a component. The function component wrapped in it can access the value passed in when ThemeContext.Provider is declared, and render again when the value of ThemeContext.Provider changes.

  • Use

    ReactDom.render(
        <App theme='dark'/>,
        document.getElementById('app')
    )
  • Effect
  • Whole Chestnut:

    import ReactDom from 'react-dom'
    import React from 'react'
    
    const ThemeContext = React.createContext('theme');
    
    class ThemedButton extends React.Component {
    
        render() {
            return <ThemeContext.Consumer>
                {
                    (value) => <div>{value}</div>
                }
            </ThemeContext.Consumer>
        }
    }
    
    class App extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                theme: 'dark'
            }
        }
    
        render() {
            return (
                <ThemeContext.Provider value={this.state.theme}>
                    <ThemedButton/>
                    <button onClick={() => this.handleChangeTheme()} className='btn btn-primary'> Modify theme</button>
                </ThemeContext.Provider>
            );
        }
    
        handleChangeTheme() {
            this.setState({
                theme: this.state.theme === 'light' ? 'dark' : 'light'
            })
        }
    }
    
    ReactDom.render(
        <App theme='dark'/>,
        document.getElementById('app')
    )

Posted by chetanrakesh on Wed, 04 Dec 2019 20:10:42 -0800