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
- 创建一个Context React.createContext(defaultValue) defaultValue是一个默认值
const ThemeContext = React.createContext('success')
- 通过Context.Provider 项组件树中引入要共享的值 值通过value属性指定
<ThemeContext.Provider value="danger"></ThemeContext.Provider>
- App组件需要和ThemeButton共享颜色 且App为上层组件 所以它需要提供这个主题色
export default class App extends Component {
render () {
return (<div>
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
</div>)
}
- 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>)
}
}
- 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两个参数 第二次执行传入组件 然后返回一个组件