特别注意
- 通过学习React组件间的通信方式,笔者总结以下两个重要的知识点
- 高层级传递给低层级—高层级用非函数
- '' 低层级传递给高层级 ''—高层级用函数(callback)
props
import React, { Component } from 'react'
{/*
1. Props组件传递函数给Son1组件
2. Son1组件添加用户后调用传递过来的函数,通过setState()修改Props组件的状态
3. Props组件重新调用render生命周期函数,然后将更新后的状态传递给Son2组件进行渲染
*/}
{/* Props组件负责存储状态 */}
export default class Props extends Component {
state = {
users: [
{name: "hao",age: 20,id: "1"},
{name: "moon",age: 21,id: "2"},
]
}
// 传递给Son1组件的回调函数
updateState = (newUser) => {
// 将获取到Son1组件调用此函数的参数进行相应的更新
this.setState({
users: [...this.state.users,newUser]
})
}
render() {
return (
<div>
{/* Son1组件负责添加一个用户 */}
<Son1 updateState={this.updateState}/>
{/* Son2组件负责渲染所有用户 */}
<Son2 users={this.state.users}/>
</div>
)
}
}
class Son1 extends Component {
nameRef = React.createRef()
ageRef = React.createRef()
addUser = () => {
let name = this.nameRef.current.value
let age = this.ageRef.current.value
let id = "3"
this.props.updateState({
name,
age,
id
})
}
render() {
return (
<div>
姓名:<input type="text" name="name" ref={this.nameRef}/>
年龄:<input type="text" name="age" ref={this.ageRef}/>
<button onClick={this.addUser}>添加一名用户</button>
</div>
)
}
}
class Son2 extends Component {
render() {
// console.log(this.props)
return (
<div>
<ul>
{
this.props.users.map(ele => {
return <li key={ele.id}>{ele.name}-{ele.age}</li>
})
}
</ul>
</div>
)
}
}
- 而且父组件可以通过ref来获取到子组件的vdom,从而得到子组件的实例对象
import React,{ Component } from 'react'
{/*
1. Ref组件通过jsx标签的ref属性来获取Son组件的实例对象
2. 然后就可以在Ref组件中使用Son组件的变量和方法
*/}
export default class Ref extends Component {
render() {
return (
<div>
<h1>父组件</h1>
<Son ref={cNode => (this.componentExample = cNode)}/>
</div>
)
}
componentDidMount() {
let {state,sonFunc} = this.componentExample
let {data} = state
alert(`父组件查看子组件数据:${data}`)
sonFunc()
}
}
class Son extends Component {
state = {
data: 'sonCompoent'
}
sonFunc = () => {
alert('父组件调用子组件的函数(sonFunc)')
}
render() {
return (
<h1>子组件</h1>
)
}
}
消息订阅与发布
- 倾向于兄弟组件(非嵌套组件)
- 如:PubSubJS
- 在 接受数据的组件 订阅消息
- 传输数据的组件 进行相应的消息发布
- 在 订阅消息的组件 卸载时执行的componentWillUnmount函数体内取消订阅
Context
- 使用同一个Context对象,由Provider提供数据给它包裹的所有组件-即Consumer
- 所有组件均可,倾向于跨级组件
- 最好用一个单独文件导出创建的Context对象
// 1. 创建并导出Context对象
import React from 'react'
export const MyContext = React.createContext("defaultValue")
import { MyContext } from './MyContext'
export default class Context extends Component {
state = {
msg: "Context-倾向于跨级传递或兄弟组件"
}
render() {
return (
<div>
{/* 2. 用Provider包裹需要渲染的跨级组件 */}
<MyContext.Provider value={this.state.msg}>
<ContextSon/>
</MyContext.Provider>
</div>
)
}
}''
class ContextSon extends Component {
render() {
return (
<ContextSonSon/>
)
}
}
class ContextSonSon extends Component {
// 声明此静态属性并接收context后才能获取
static contextType = MyContext
render() {
return (
<div>
<h4>
<span>用this.context获取:{this.context}</span>
<hr/>
<span>用Consumer获取:</span>
<MyContext.Consumer>
{
value => (<span>{value}</span>)
}
</MyContext.Consumer>
</h4>
</div>
)
}
}
- 接收数据的组件为function component
function ContextSonSon() {
return (
<div>
<h4>
<span>用Consumer获取:</span>
<MyContext.Consumer>
{
value => (<span>{value}</span>)
}
</MyContext.Consumer>
</h4>
</div>
)
}
RenderProps
render
- 子组件中预留组件,而此预留组件由父组件来确定并将子组件传递的数据给此预留组件(React)
import React, { Component } from 'react'
export default class RenderProps extends Component {
render() {
return (
<div>
<Son render={(data)=>(<OtherComponent msg={data}/>)}/>
</div>
)
}
}
class Son extends Component {
state = {
msg: `Son组件预留一个组件位置,
RenderProps组件来确定需要渲染的组件并获取Son组件传递过来的信息(Vue-Slot)`
}
render() {
return (
<div>
<h3>-Son</h3>
{this.props.render(this.state.msg)}
</div>
)
}
}
// 不是比Son组件层级高的组件的 其它组件
class OtherComponent extends Component {
render() {
return (
<h3>
- OtherComponent<br/>
-- {this.props.msg}
</h3>
)
}
}
children
- 利用 this.props.children 存储一般组件的文体内容
import React, { Component } from 'react'
export default class RenderProps extends Component {
render() {
return (
<div>
<h3>利用children属性,Son组件不能给OtherComponent传递数据,但仍然预留了一个组件等待RenderProps组件来确定</h3>
<Son>
<OtherComponent/>
</Son>
</div>
)
}
}
class Son extends Component {
render() {
return (
<div>
<h3>Son</h3>
{this.props.children}
</div>
)
}
}
// 不是比Son组件层级高的组件的 其它组件
class OtherComponent extends Component {
render() {
return (
<h3>
OtherComponent
</h3>
)
}
}
redux
- 集中式管理状态,此处不详细介绍它了,推荐查看react-redux和redux的官方文档
参考
- 尚硅谷react
- React ref的前世今生
- ps:该文章如有不足之处,还望之处,笔者会尽力修改它
发表评论
还没有评论,快来抢沙发吧!