Bootstrap

高阶组件、函数作为子组件、Context API

高阶组件

(封装时钟的例子的两种方法)
eg1:

import React,from "react";
class TimeClok extends React.Component{
  state = {time:new Date()}
  componentDidMount(){
    this.timerId=setInterval(()=>this.tick(),1000)
  }
  componentwillUnmount(){
    clearInterval(  this.timerId)
  }
  tick(){
    this.setState({time:new Date()})
  }
  render(){
    <div>{this.state.time}</div>
  }
}
export const TimeWrapClock = WrappedComponent =>{
  return class extends React.PureComponent {
     render(){return <TimeClok><WrappedComponent  {...this.props}/></TimeClok> }
  } 
}

eg2:

export default function TimeWrapClock(WrappedComponent){
  return class extends React.Component{
    state = {time:new Date()}
    componentDidMount(){
      this.timerId=setInterval(()=>this.tick(),1000)
    }
    componentwillUnmount(){
      clearInterval(this.timerId)
    }
    tick(){
      this.setState({time:new Date()})
    }
    render(){
      return <WrappedComponent time={this.state.time} {...this.props}/> 
    }
  }
}
使用时要引入:import TimeWrapClock from "./路径"

函数作为子组件

(实现更多场景的组件的复用)

class MyComponent extends  React.Component{
  render(){
    return (
      <div>
        {this.props.children('nate wang')}
      </div>
    )
  }
}
<MyComponent>
  {(name)=>(<div>{name}</div>)}
</MyComponent>

Context API

(适用全局性场景)

用法:
const ThemeContext = React.createContext('light')
class App extends React.Component {
  render() {
    return (
      <ThemeContext.Provider value="dark">
        <ThemedButton />
      </ThemeContext.Provider>
    )
  }
}
function ThemedButton(props) {
  return (
    <ThemeContext.Consumer >
      {theme => <Button {...props} theme={theme} />}
    </ThemeContext.Consumer>
  )
}

eg:全局语言切换的列子

import React, {Fragment} from "react";
const en={
  confirm:"Confirm",
  cancel:"Cancel"
}
const cn={
  confirm:"确认",
  cancel:"取消",
}
const ChangeLanguage = React.createContext(en)//默认英语
class LanguageProvider extends React.Component{
  state = {local:cn};
  toggleLocale=()=>{
    const local=this.state.local===en?cn:en
    this.setState({local})
  }
  render(){
    return(
      <ChangeLanguage.Provider value={this.state.local}>
          <button onClick={this.toggleLocale}>
            切换语言
          </button>
          {this.props.children}
      </ChangeLanguage.Provider>
    )
  }
}
class LanguageButtons extends React.Component{
  render(){
    return(
      <ChangeLanguage.Consumer>
        {
          (local)=>(
            <div>
              <button>{local.cancel}</button>
              <button>{local.confirm}</button>
            </div>
          )
        }
      </ChangeLanguage.Consumer>
    )
  }
}

export default ()=>{
  <div>
    <LanguageProvider>
      <div>
        <LanguageButtons/>
      </div>
    </LanguageProvider>
  </div>
}

父组件触发子组件,子组件传值给父组件(ref)

export class Father extends Component {
  constructor(props) {
    this.state = {
      showChildrenName:""
    }
  }
  handleOk=()=>{
    this.changeData((name)=>{
      this.setState({
        showChildrenName:name
      })
    })
  }
  render() {
    return (
      <div >
        <Button onClick={this.handleOk}></Button>
        <Children name={ref=> this.changeData = ref}></Children>
      </div>
    )
  }
}
export class Children extends Component {
  constructor(props) {
    this.state = {
      name: ""
    }
  }
  componentDidMount() {
    this.props.name(this.saveChildName)
  }
  saveChildName = (cb) => {
    let { name } = this.state
    cb(name)
  }
  changeName=(e)=>{
    this.setState({
      name:"宝宝"
    })
  }
  render(){
    return(
      <Input onChange={this.changeName} value={this.state.name}/>
    )
  }
}
;