美文网首页
react context API配合高阶组件的实际应用

react context API配合高阶组件的实际应用

作者: lishiwen | 来源:发表于2018-11-14 23:44 被阅读0次

    文章概览

    本文包含新版本react contextAPI的简单介绍、基本用法和实际项目中的使用方法。

    本文不会介绍context和高阶组件的概念,而是介绍二者如何配合使用。

    简介

    react在16.3版本引入了全新的context api,提供一种跨组件传递数据的方法,避免了在多组件层级间手动传递props。

    基本用法

    项目中很多组件需要共有的状态比如:主题、地区偏好。如何优雅的处理呢?当然了,借助redux、mobx这些状态库可以轻松实现。但是小项目中无需引入redux等增加复杂度,让新手迷惑。

    我们考虑使用context如何处理上边的问题,下边的例子为按钮添加light或dark主题:

    • 创建主题context
    
    const THEME = {
    
        light: "light",
    
        dark: "dark",
    
    };
    
    const ThemeContext = React.createContext(THEME.light);
    
    
    • 使用主题
    
    class ButtonCus extends Component{
    
        render() {
    
            return (
    
                <ThemeContext.Consumer>
    
                    {theme => (
    
                        <button className={theme}>button</button>
    
                    )}
    
                </ThemeContext.Consumer>
    
            );
    
        }
    
    }
    
    
    light

    现在按钮使用context创建时默认的主题light,如果想使用dark主题需要显示提供Provider进行切换,像这样:

    
    <ThemeContext.Provider value={THEME.dark}>
    
        <ButtonCus/>
    
    </ThemeContext.Provider>
    
    

    效果:

    dark

    context的简单使用就是这样


    如果每个组件都写一个Consumer,那将是多么痛苦的事。有没有简洁点的不用每次都写Consumer,能不能实现动态切换主题?

    答案是肯定的

    接下来将切换主题的接口放入context,实现在嵌套层级中切换主题;将Consumer封装在高阶组件中实现简洁的使用Consumer;

    • 在顶层将当前应用的主题和切换主题的方法作为context的值向下传递

    这里需要将组件状态作为Provider的值传递

    
    class App extends Component{
    
        constructor(props){
    
            super(props);
    
            this.switchTheme = this.switchTheme.bind(this);
    
            //将当前应用的主题和切换主题的方法作为context的值向下传递
    
            this.state = {
    
                theme: THEME.light,
    
                switchTheme: this.switchTheme
    
            };
    
        }
    
        switchTheme() {
    
            this.setState(state => {
    
                return {
    
                    theme: state.theme === THEME.light
    
                        ? THEME.dark
    
                        : THEME.light
    
                }
    
            })
    
        }
    
        render(){
    
            return(
    
                <div>
    
                    <ThemeContext.Provider value={this.state}>
    
                        <ButtonCus/>
    
                        <ButtonCus/>
    
                        <ButtonCus/>
    
                        <ButtonCus/>
    
                    </ThemeContext.Provider>
    
                </div>
    
            )
    
        }
    
    }
    
    
    • 高阶组件封装context的使用逻辑
    
    //高阶组件将contest的使用逻辑提取出来,需要应用主题的组件只需像使用普通props一样使用主题即可
    
    function withContext(Comp) {
    
        return function (props) {
    
            return (
    
                <ThemeContext.Consumer>
    
                    {theme => <Comp {...props} theme={theme}/>}
    
                </ThemeContext.Consumer>
    
            )
    
        }
    
    }
    
    
    • 修改之前的Component 组件

    任意组件只要使用withContext包裹后都可以收到名为theme的属性,将其应用在合适的位置即可。

    
    class ButtonCus extends Component{
    
        render() {
    
            return (
    
                <button
    
                    className={this.props.theme.theme}
    
                    onClick={this.props.theme.switchTheme}>button
    
                </button>
    
            );
    
        }
    
    }
    
    //使用高阶组件将普通组件应用上主题, 将高阶组件返回的组件赋值为用户命名组件,便于使用
    
    ButtonCus = withContext(ButtonCus);
    
    export {ButtonCus}
    
    
    withTheme

    到此,点击任意按钮都可以切换全局主题。

    后记

    context有能力处理全局状态,配合高阶组件简化繁琐的代码,意味着小型应用完全可以使用context处理全局状态。当然redux/mobx管理大型应用状态会更加优秀。

    相关链接

    本文完整代码示例

    新浪微博

    相关文章

      网友评论

          本文标题:react context API配合高阶组件的实际应用

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