组件是独立且封闭的单元,默认情况下,只能使用组件自己的数据。
在组件化过程中,我们将一个完整的功能 拆分成多个组件,以更好的完成整个应用的功能。
而在这个过程中,多个组件之间不可避免的要共享某些数据 。
为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通。这个过程就是组件通
一、props基础 1.1 概述组件是封闭的,要接收外部数据应该通过props来实现
props的作用:接收传递给组件的数据
传递数据:给组件标签添加属性
接收数据:函数组件通过参数props接收数据,类组件通过this.props接收数据
1.2 函数组件通讯
Demo.js
// 函数组件
// 方式1
// export default function Demo(props) { // 或下面这种写法--解构
export default function Demo({car, money, check}) {
// console.log(props);
return (
Demo组件
{
/**方式1
* {props.car}
{props.money}
{props.check ? '是' : '否'}
*/
}
{
// 方式2
}
{car}
{money}
{check ? '是' : '否'}
)
}
index.js
/**
* 1. 导入react和react-dom
* 2. 创建 react 元素
* 3. 把 react 元素渲染到页面
*/
import React from 'react';
import ReactDom from 'react-dom/client';
import { Component } from 'react';
import Demo from './Demo'
class App extends Component {
render() {
return
APP组件
{
/**
* 1. 通过属性的方式,给组件提供数据
* 2. 子组件中通过 props 就可以获得参数
*/
}
}
}
// 幽灵节点:节点不会渲染任何的内容,跟 vue 里面的 template 标签一样
const element = (
);
// 参数1:渲染的 react 元素即虚拟 DOM
// 参数2:需要渲染到哪个容器中
const root = ReactDom.createRoot(document.getElementById('root'));
root.render(element);
1.3 类组件通讯
Hello.js
/**
* 1. 导入react和react-dom
* 2. 创建 react 元素
* 3. 把 react 元素渲染到页面
*/
import React from 'react';
import { Component } from 'react';
export default class Hello extends Component {
render() {
// 类组件中直接通过 this 就可以访问 props
// console.log(this.props);
const {car, money, check} = this.props;
return (
类组件
{car}
{money}
{check ? '是' : '否'}
)
}
}
index.js
/**
* 1. 导入react和react-dom
* 2. 创建 react 元素
* 3. 把 react 元素渲染到页面
*/
import React from 'react';
import ReactDom from 'react-dom/client';
import { Component } from 'react';
import Demo from './Demo'
import Hello from './Hello'
class App extends Component {
render() {
return
APP组件
{
/**
* 1. 通过属性的方式,给组件提供数据
* 2. 子组件中通过 props 就可以获得参数
*/
}
}
}
// 幽灵节点:节点不会渲染任何的内容,跟 vue 里面的 template 标签一样
const element = (
);
// 参数1:渲染的 react 元素即虚拟 DOM
// 参数2:需要渲染到哪个容器中
const root = ReactDom.createRoot(document.getElementById('root'));
root.render(element);
1.4 props的特点
可以给组件传递任意类型的数据
props是只读的,不允许修改props的数据
Demo.js
// 函数组件
// 方式1
export default function Demo(props) { // 或下面这种写法--解构
// export default function Demo({car, money, check, name}) {
console.log(props);
return (
Demo组件
{
/**方式1
*
*/
}
{props.car}
{props.money}
{props.check ? '是' : '否'}
{props.name}
子组件:{props.money}
{
// 方式2
/**
* {car}
{money}
{check ? '是' : '否'}
{name}
*/
}
)
}
index.js
/**
* 1. 导入react和react-dom
* 2. 创建 react 元素
* 3. 把 react 元素渲染到页面
*/
import React from 'react';
import ReactDom from 'react-dom/client';
import { Component } from 'react';
import Demo from './Demo'
class App extends Component {
state = {
money: 100
}
render() {
return
APP组件
{
/**
* 1. 通过属性的方式,给组件提供数据
* 2. 子组件中通过 props 就可以获得参数
*/
}
{console.log(1);}}
list={[1,2,3]}
obj = {{age: 12}}
content = {内容}
>
父组件:{this.state.money}
}
Add = () => {
this.setState({
money: this.state.money + 10
})
}
}
// 幽灵节点:节点不会渲染任何的内容,跟 vue 里面的 template 标签一样
const element = (
);
// 参数1:渲染的 react 元素即虚拟 DOM
// 参数2:需要渲染到哪个容器中
const root = ReactDom.createRoot(document.getElementById('root'));
root.render(element);
注意:在类组件中使用的时候,需要把props传递给super(),否则构造函数无法获取到props
Hello.js
/**
* 1. 导入react和react-dom
* 2. 创建 react 元素
* 3. 把 react 元素渲染到页面
*/
import React from 'react';
import { Component } from 'react';
export default class Hello extends Component {
constructor(props) {
super(props)
this.state = {
money: this.props.money + 100
}
}
render() {
console.log(this.props);
return (
类组件
{this.state.money}
)
}
}
index.js
/**
* 1. 导入react和react-dom
* 2. 创建 react 元素
* 3. 把 react 元素渲染到页面
*/
import React from 'react';
import ReactDom from 'react-dom/client';
import { Component } from 'react';
import Hello from './Hello'
class App extends Component {
state = {
money: 100
}
render() {
return
APP组件
{
/**
* 1. 通过属性的方式,给组件提供数据
* 2. 子组件中通过 props 就可以获得参数
*/
}
}
Add = () => {
this.setState({
money: this.state.money + 10
})
}
}
// 幽灵节点:节点不会渲染任何的内容,跟 vue 里面的 template 标签一样
const element = (
);
// 参数1:渲染的 react 元素即虚拟 DOM
// 参数2:需要渲染到哪个容器中
const root = ReactDom.createRoot(document.getElementById('root'));
root.render(element);
二、组件通讯三种方式
父传子
子传父
非父子
2.1 父传子父组件提供要传递的state数据
给子组件标签添加属性,值为 state 中的数据
子组件中通过 props 接收父组件中传递的数据
index.js
/**
* 1. 导入react和react-dom
* 2. 创建 react 元素
* 3. 把 react 元素渲染到页面
*/
import React from 'react';
import ReactDom from 'react-dom/client';
import { Component } from 'react';
import Child from './Child'
class App extends Component {
state = {
usercount: ''
}
render() {
return (
账号:
)
}
addusercount = (e) => {
this.setState({
usercount: e.target.value
})
}
}
// 幽灵节点:节点不会渲染任何的内容,跟 vue 里面的 template 标签一样
const element = (
);
// 参数1:渲染的 react 元素即虚拟 DOM
// 参数2:需要渲染到哪个容器中
const root = ReactDom.createRoot(document.getElementById('root'));
root.render(element);
Child.js
export default function Child({usercount}) {
return (
子组件
账号为:{usercount}
)
}
2.2 子传父
思路:利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数。
父组件提供一个回调函数(用于接收数据)
将该函数作为属性的值,传递给子组件
子组件通过 props 调用回调函数
将子组件的数据作为参数传递给回调函数
Child.js
/**
* 1. 导入react和react-dom
* 2. 创建 react 元素
* 3. 把 react 元素渲染到页面
*/
import React from 'react';
import { Component } from 'react';
export default class Child extends Component {
state = {
usercount: ''
}
render() {
return (
子组件
账号为:
)
}
addusercount = (e) => {
this.setState({
usercount: e.target.value
})
// 传递给父组件
this.props.changeUsercount(e.target.value)
}
}
index.js
/**
* 1. 导入react和react-dom
* 2. 创建 react 元素
* 3. 把 react 元素渲染到页面
*/
import React from 'react';
import ReactDom from 'react-dom/client';
import { Component } from 'react';
import Child from './Child';
class App extends Component {
state = {
sonUsercount: ''
}
render() {
return (
父组件
子组件传递过来的账号为:{this.state.sonUsercount}
)
}
changeUsercount = (usercount) => {
// console.log('接收子组件传递过来的账号:', usercount);
this.setState({
sonUsercount: usercount
})
}
}
// 幽灵节点:节点不会渲染任何的内容,跟 vue 里面的 template 标签一样
const element = (
);
// 参数1:渲染的 react 元素即虚拟 DOM
// 参数2:需要渲染到哪个容器中
const root = ReactDom.createRoot(document.getElementById('root'));
root.render(element);
2.3 兄弟组件通讯
三、context跨级组件
四、props进阶
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)