组件通信
父组件与子组件通信
- 父组件将自己的状态传递给子组件,子组件当做属性来接收,当父组件更改自己状态的时候,子组件接收到的属性就会发生改变
- 父组件利用ref对子组件做标记,通过调用子组件的方法以更改子组件的状态,也可以调用子组件的方法…
子组件与父组件通信
- 父组件将自己的某个方法传递给子组件,在方法里可以做任意操作,比如可以更改状态,子组件通过this.props接收到父组件的方法后调用。
//父组件
import React, { Component,Fragment } from 'react'
import Child from './Child'
import Girl from './Girl'
class Father extends Component {
static defaultProps = {
childName: '王麻子'
}
constructor () {
super()
this.state = {
taiji: '王麻子家专有胎记'
}
}
changeTaiji = () => {
this.setState({
taiji: '李四家的'
})
}
zhengrong = () => {
this.setState({
taiji: '王五家的'
})
}
charaChange = () => {
this.girl.charaHandler()
}
render () {
console.log( this ) // child refs.child girl this.girl
const { childName } = this.props
const { taiji } = this.state
return (
<Fragment>
<h3>
这里是Father组件
</h3>
<button onClick = { this.charaChange }> 父组件来修改子组件的状态 </button>
<hr/>
<button onClick = { this.changeTaiji }> 更改胎记 </button>
<Child change = { this.charaChange } ref = 'child' name = { childName } taiji = { taiji } zhengrong = { this.zhengrong }></Child>
<Girl ref = { el => this.girl = el }/>
</Fragment>
)
}
}
export default Father
//子组件
import React, { Component,Fragment } from 'react'
class Child extends Component {
render () {
const { name,taiji,zhengrong,change } = this.props
return (
<Fragment>
<h3>
这里是Child组件
</h3>
<button onClick = { zhengrong }> 整容 </button>
<button onClick = { change }> 更改girl的性格 </button>
<p> name: { name } </p>
<p> taiji: { taiji } </p>
</Fragment>
)
}
}
export default Child
//另一个子组件
import React , { Component,Fragment } from 'react'
class Girl extends Component{
constructor () {
super()
this.state = {
chara: '萝莉型的'
}
}
charaHandler = () => {
this.setState(() => {
return {
chara: '御姐型'
}
})
}
render () {
const { chara } = this.state
return (
<Fragment>
<h3> 这里是girl </h3>
<button onClick = { this.charaHandler }> 性格 </button>
<p> 女孩的性格: { chara } </p>
</Fragment>
)
}
}
export default Girl
跨组件通信
在react没有类似vue中的事件总线来解决这个问题,我们只能借助它们共同的父级组件来实现,将非父子关系装换成多维度的父子关系。react提供了context api来实现跨组件通信, React 16.3之后的contextapi较之前的好用。
//gradfather.js
import React , { Component,Fragment } from 'react';
import Father from './Father'
// 1. 创建一个context ( 上下文/ 投影 )
import { ThemeContext,MoneyContext } from './context';
class GradFather extends Component {
constructor () {
super()
this.state = {
money: 3000
}
}
render () {
const { money } = this.state
return (
<Fragment>
<h3> 这里是GradFather </h3>
<hr/>
{/* <ThemeContext.Provider value = "1000">
<Father/>
</ThemeContext.Provider> */}
<MoneyContext.Provider value = { money }>
<Father></Father>
</MoneyContext.Provider>
</Fragment>
)
}
}
export default GradFather
//father.js
import React , { Component,Fragment } from 'react';
import Son from './Son'
class Father extends Component {
render () {
return (
<Fragment>
<h3> 这里是Father </h3>
<hr/>
<Son/>
</Fragment>
)
}
}
export default Father
//son.js
import React , { Component,Fragment } from 'react';
import { ThemeContext,MoneyContext } from './context';
class Son extends Component {
static contextType = MoneyContext
render () {
return (
<Fragment>
<h3> 这里是son </h3>
<p> { this.context } </p>
</Fragment>
)
}
}
export default Son
/content.js
import React from 'react'
export const ThemeContext = React.createContext( )
export const MoneyContext = React.createContext( )
HOC(高阶组件)
Higher-Order Components就是一个函数,传给它一个组件,它返回一个新的组件。
const NewComponent = higherOrderComponent(YourComponent)
比如,我们想要我们的组件通过自动注入一个版权信息。
// withCopyright.js 定义一个高阶组件
import React, { Component, Fragment } from 'react'
const withCopyright = (WrappedComponent) => {
return class NewComponent extends Component {
render() {
return (
<Fragment>
<WrappedComponent />
<div>©版权所有 千锋教育 2019 </div>
</Fragment>
)
}
}
}
export default withCopyright
// 使用方式
import withCopyright from './withCopyright'
class App extends Component {
render () {
return (
<div>
<h1>Awesome React</h1>
<p>React.js是一个构建用户界面的库</p>
</div>
)
}
}
const CopyrightApp = withCopyright(App)