高階組件接收組件做爲參數,返回新的組件
const EnhancedComponent = higherOrderComponent(WrappedComponent)
這種模式一般使用函數來實現,基本上是一個類工廠(是的,一個類工廠!)。react
withTimer.jsapp
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.jside
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 主要由如下三部分組成:this
React.createContext 用於傳遞 初始值返回一個包含 provider 和 consumer 的對象spa
const enStrings = { submit:'Submit', cancel:'Cancel' }; const cnStrings = { submit:'提交', cancel:'取消' }; const LocaleContext = React.createContext(enStrings);
provide 函數使用 higher,並能夠接收任何值code
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 不是組件)。component
class LocaledButton extends React.Component{ render(){ return( <LocaleContext.Consumer> { locale => ( <div> <button> {locale.cancel} </button> <button> {locale.submit} </button> </div> ) } </LocaleContext.Consumer> ) } } class App extends React.Component{ render(){ return( <div> <LocalProvider> <div> <br/> <LocaledButton> </LocaledButton> </div> </LocalProvider> </div> ) } }