高阶组件接收组件作为参数,返回新的组件
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> <button> {locale.submit} </button> </div> ) } </LocaleContext.Consumer> ) } } class App extends React.Component{render(){ return( <div> <LocalProvider> <div> <br/> <LocaledButton> </LocaledButton> </div> </LocalProvider> </div> ) } }