组件通信
- 父子通信
- 父组件将一个数据传递给子组件,但是这个数据只有父组件有权利更改,子组件不可以
```class Father extends Component{
constructor(){
super()
this.state={
name:'臭弟弟'
}
}
changeName = () =>{
this.setState ({
name:'俊哥哥'
})
}
render(){
let {name} = this.state
return(
<Fragment>
<h3> 父组件 </h3>
<button onClick={this.changeName}>改名字 </button>
<Son name= {name} ></Son>
</Fragment>
)
}
}
class Son extends Component{
render(){
let {name} = this.props
return(
<Fragment>
<h4> 子组件 </h4>
<p>我给自己取了个名字: {name} </p>
</Fragment>
)
}
}
export default Father
- ref链绑定
- ref = “son”
- ref = { el => this.el = el} 如果是一个函数,这里的el指的就是当前组件 import React
class Father extends Component{
changeName = () =>{
this.son.setState({
name:'俊哥哥'
})
}
render(){
return(
<Fragment>
<h3> 父组件 </h3>
<button onClick={this.changeName}> 取名字 </button>
<Son ref={el=>this.son=el }></Son>
</Fragment>
)
}
}
class Son extends Component{
constructor(){
super()
this.state={
name:'臭弟弟'
}
}
render(){
let {name} = this.state
return(
<Fragment>
<h4>子组件</h4>
<p> 我给自己取名字{name} </p>
</Fragment>
)
}
}
export default Father
- 子父通信
父组件传递一个方法给子组件
class Father extends Component{
constructor(){
super()
this.state={
name:'臭弟弟'
}
}
changeName = () =>{
this.setState ({
name:'俊哥哥'
})
}
render(){
let {name} = this.state
return(
<Fragment>
<h3> 父组件 </h3>
<Son name= {name} change={this.changeName}></Son>
</Fragment>
)
}
}
class Son extends Component{
render(){
let {name,changeName} = this.props
return(
<Fragment>
<h4> 子组件 </h4>
<button onClick={changeName}>改名字 </button>
<p>我给自己取了个名字: {name} </p>
</Fragment>
)
}
}
export default Father
3. 跨组件通信
context
原先的跨组件传递要一级一级的传递数据,这种形式很是低效,context的出现解决了这个低效的方案
context 使用步骤:
1. 创建context
` const MoneyContext = React.crateContext(默认值) `
2. 使用 创建的Context包裹目标组件的父组件
```javascript
<MoneyContext.Provider value = "2000">
<Father></Father>
</MoneyContext.Provider>
```
3. 在目标组件中定义一个类属性 , 这个类属性叫做 contextType
4. 直接在目标组件中 通过 this.context 就可以获得数据了
```javascript
class Son extends Component {
static contextType = MoneyContext
render () {
return (
<Fragment>
<h3> son 组件 </h3>
<p> 爷爷给了我: { this.context } </p>
</Fragment>
)
}
}
完整代码
const MoneyContext = React.createContext('1000')
class GrandFather extends Component{
constructor(){
super()
this.state={
money:1000
}
}
render(){
return(
<Fragment>
<h2> GrandFather </h2>
<MoneyContext.Provider value="2000">
<Father></Father>
</MoneyContext.Provider>
</Fragment>
)
}
}
class Father extends Component{
render(){
return(
<Fragment>
<h3> Father</h3>
<Son></Son>
</Fragment>
)
}
}
class Son extends Component{
static contextType = MoneyContext
render(){
return(
<Fragment>
<h4>Son </h4>
<p>爷爷给了我 : {this.context}</p>
</Fragment>
)
}
}
export default GrandFather
- 非父子组件通信( 多组件状态共享 )
-
- react-router (react路由版本3)/ react-router-dom(react路由版本4)
- flux
- redux
- mobx
HOC ( Higher Order Component) 高阶组件
-
高阶组件
高阶组件就是一个函数, 这个函数接收一个参数, 这个参数是一个组件 -
格式
const Hoc = ( Comp ) => { return class 类名称 extends React.Component { render () { return <Comp></Comp> } } } //这里的Hoc就是一个高阶组件
-
高阶组件的好处 / 功能
组件复用
接下来以一个案例的形式,来说明一个高阶组件
import React, { Component } from 'react'; // 高阶组件 const Hoc = ( Comp ) => { return class Banner extends Component{ banner () { //假设我定义个方法,这个方法就是实现一个轮播图 return 'banner' } render () { return <Comp banner = { this.banner }></Comp> } } } class A extends Component { render () { return ( <div> <h3> A组件 </h3> { this.props.banner() } </div> ) } } class B extends Component { render () { return ( <div> <h3> b组件 </h3> { this.props.banner() } </div> ) } } const HocA = Hoc( A ) const HocB = Hoc( B ) class C extends Component { render () { return ( <div> <h3> C组件 </h3> <HocA></HocA> <hr/> <HocB></HocB> </div> ) } } export default C
react-router
-
我使用的是4.+版本,使用的是react-router-dom
-
react-router是3.x的版本
-
路由的模式有两种
- 老浏览器提供的 hash模式, 我们称之为: HashRouter
- H5提供的的 hsitory 模式,我们称之为 BrowserRouter
注意: H5模式的路由需要后端支持
-
使用路由
-
书写路由展示区域, 使用 Route
-
重定向
- 第一种
<Route to = "/" component = { Home }/>
- 第二种
- 路径完全匹配 exact
<Route to = "/" component = { Home } exact/>