乐趣区

React学习之高阶组件及Context-API

高阶组件接收组件作为参数,返回新的组件

const EnhancedComponent = higherOrderComponent(WrappedComponent)

这种模式通常使用函数来实现,基本上是一个类工厂(是的,一个类工厂!)。

withTimer.js

import React,{Component} from 'react'

export default function withTimer(WrappedComponent){
    return class extends Component{
        state = {time:new Date(),
            timerID:0
        };
        componentDidMount(){this.timerID = setInterval(()=> this.tick(),1000);

        }
        tick(){
            this.setState({time:new Date()
            })
        }
        componentWillUnmount(){clearInterval(this.timerID)
        }

        render(){return <WrappedComponent  time={this.state.time} {...this.props}/>
        }
    }
}

App.js

import React,{Component} from 'react'
import withTimer from './withTimer'
class App extends Component{render(){
        return(
            <div>
                <p>
                hahha
                </p>
                <p>
                    {this.props.time.toLocaleString()}
                </p>
            </div>
        )
    }
}

export default withTimer(App)

Context API

当应用中多个组件需要使用全局状态时,这时可以使用 Context API

新的 context API 主要由以下三部分组成:

  • React.createContext 用于传递 初始值返回一个包含 provider 和 consumer 的对象

    const enStrings = {
        submit:'Submit',
        cancel:'Cancel'
    };
    
    const cnStrings = {
        submit:'提交',
        cancel:'取消'
    };
    
    const LocaleContext = React.createContext(enStrings);
    
  • provide 函数使用 higher,并可以接收任何值

     class LocalProvider extends React.Component{
        state = {locale:cnStrings};
        toggleLocale = () => {
            const locale = this.state.locale === enStrings
                        ?cnStrings
                        :enStrings;
            this.setState({locale})            
        };
        render(){
            return(<LocaleContext.Provider value={this.state.locale}>
                    <button onClick={this.toggleLocale}>
                        切换语言
                    </button>
                    {this.props.children}
                </LocaleContext.Provider>
            )
        }
    }
  • consume 函数在 provider 之后任何地方使用,并传递一个返回 JSX 的函数(这有点像 render prop 组件,但 consume 不是组件)。

    class LocaledButton extends React.Component{render(){
            return(
                <LocaleContext.Consumer>
                    {
                        locale => (
                            <div>
                                <button>
                                    {locale.cancel}
                                </button>&nbsp;
                                <button>
                                    {locale.submit}
                                </button>
                            </div>
                        )
                    }
                </LocaleContext.Consumer>
            )
        }
    }
    
    class App extends React.Component{render(){
            return(
                <div>
                <LocalProvider>
                    <div>
                        <br/>
                        <LocaledButton>
    
                        </LocaledButton>
                    </div>
                </LocalProvider>
            </div>
            )
        }
    }
退出移动版