react----组合 Context 高阶组件

1,726 阅读3分钟

react 中也有类似 也有类似vue的slot的机制 即可以获取标签中包裹的内容 这种机制称为组合

获取组件标签包裹的内容通过props.children

①通过this.props.children获取包裹内容(插入全部内容到指定位置) 在子组件中需要使用到父组件中使用子组件时包裹的内容,使用{this.props.children}放置在我们需要放置父组件使用子组件包裹的内容的位置上,最后这个this.props.children会被替换成父组件使用子组件时候再子组件标签中包裹的内容

子组件Panel.js:

 render () {
    return (<div className="panel panel-danger">
        {this.props.children}    // 最终这里会替换成Panel被使用时其标签中包裹的全部内容
    </div>)
  }

父组件:

 render () {
    return (<div className="panel panel-danger">
       <Panel>
            <h1>我会被传给子组件的的props.children哦</h1>
            <p>我也会被传给子组件的的props.children哦</p>
        </panel>
    </div>)
  }

②:使用props来插入(插入指定内容到全部位置) 在子组件中使用{this.props.属性名}来放置,然后在父组件中使用子组件的时候通过props将jsx元素传过来

子组件Panel.js:

 render () {
    return (<div className="panel panel-danger">
        {this.props.h1}    // 最终这里会替换成Panel被使用时通过props传过来的名为h1的内容
    </div>)
  }

父组件:

let h1 = <h1>我会被传给子组件的的props.children哦</h1>
 render () {
    return (<div className="panel panel-danger">
       <Panel  h1={h1} />  // 将h1这个jsx对象通过props传给子组件
    </div>)
  }

Context 提供一种在组件之间共享此类值的方法 不必显示地通过组件树的逐层传递props

  1. 创建一个Context React.createContext(defaultValue) defaultValue是一个默认值
const ThemeContext = React.createContext('success')
  1. 通过Context.Provider 项组件树中引入要共享的值 值通过value属性指定
<ThemeContext.Provider value="danger"></ThemeContext.Provider>
  1. App组件需要和ThemeButton共享颜色 且App为上层组件 所以它需要提供这个主题色
export default class App extends Component {
  render () {
    return (<div>
      <ThemeContext.Provider value="dark">
        <Toolbar />
      </ThemeContext.Provider>
    </div>)
  }
  1. Context.contextType
  • 若是class声明的组件 底层组件使用上面的Provider提供的值 需要在组件中 声明contextType静态属性 值是要获取得值的Context
  • 然后在组件中就可以通过this.context获取Provider的value属性在指定的共享的值
  • 若在constructor中使用context,constructor的第二个参数就是context的值
  • react会向上层寻找 找到最近的ThemeContext的Provider的value 这个value会传给constructor的第二个参数
  • 在constructor以外其他函数中可以通过this.context刚问该值 render函数中也可以
import React,{Component} from 'react'
//创建一个context
const ThemeContext = React.createContext('light')
class ThemeButton extends Component{
    static contextType = ThemeContext
    constructor(props,context){
        super()
        console.log(context)
    }
    render(){
        return(
        <div>
        <button className = {`btn btn-${this.context.theme}`}>{this.context.theme}</button>
        </div>
        )
    }
}
class Toolbar extends Component {
  render () {
    return <div>
      <ThemeButton />
    </div>
  }
}

export default class App extends Component {
  render () {
    return (<div>
      <ThemeContext.Provider value={{theme: 'success'}}>
        <Toolbar />
      </ThemeContext.Provider>
    </div>)
  }
}

  1. Context.Consumer 在函数中使用context 在函数式的组件中使用Context共享数据的值 需使用Consumer组件
function ThemeButton(props) {
  return (<ThemeContext.Consumer>
    {
      value => <button className={`btn btn-${value.theme}`}>{value.theme}</button>
    }
  </ThemeContext.Consumer>)
}

高阶组件connect 将很多代码功能相同的部分抽离成一个高阶组件 把不同的部分当成参数 可以被连续执行两次及以上的函数(通过必报保存第一次数据然后返回一个函数工第二次执行 与Function.bind类似)

//普通写法
function connect(){
    return function(){
        
    }
}

//箭头函数写法

let connect = ()=>()=>{}

react 的高阶组件实现 指定 connect两次后执行会返回一个组件 第一次执行传入mapStateToProps 和 mapDispatchToProps两个参数 第二次执行传入组件 然后返回一个组件