React -- 3/100 】组件通讯
通讯 | props | prop-types
组件通讯
Props: 组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props
/* class */
.parent-box {
width: 700px;
height: 300px;
background-color: #eeeeee;
border: 1px solid #ca46dd;
}
.child-box {
width: 500px;
height: 200px;
background-color: #c4ee9f;
}
.grandchild-box {
width: 300px;
height: 100px;
background-color: #c05b76;
}
1 - 使用function
const Demo = (props) => {
console.log(props)
return (
<div>
{props.info}
<p>姓名: {props.name}</p>
<p>年龄: {props.age}</p>
<div>喜欢的颜色:
{props.Colors.map( item =>
<li key={item}>{item}{item}</li>
)}
</div>
{props.func()}
</div>
)
};
ReactDOM.render(
<Demo
info = { <h5>cnyangx的个人信息</h5> }
name="cnyangx"
age={24}
Colors={['red', 'green', 'blue']}
func={ () => console.log('React props Demo')} />,
document.getElementById('root'));
![](https://img2018.cnblogs.com/blog/1778682/201912/1778682-20191204163656913-2018895475.png)
2 - 使用class
/**
注意: 使用类组件时,如果写了构造函数,应该将props传递给super(),否则,无法在构造函数中获取到props
*/
import React from 'react'
// class 组件
class PropsDemo extends React.Component{
constructor(props){
super(props);
}
render() {
return (
<div>
<h2>class 组件</h2>
{this.props.info}
<p>姓名: {this.props.name}</p>
<p>年龄: {this.props.age}</p>
<div>喜欢的颜色:
{this.props.Colors.map( item =>
<li key={item}>{item}{item}</li>
)}
</div>
{this.props.func()}
</div>
)
}
}
export default PropsDemo;
// 在页面中使用
ReactDOM.render(
<PropsDemo
info = { <h5>cnyangx的个人信息</h5> }
name="cnyangx"
age={24}
Colors={['red', 'green', 'blue']}
func={ () => console.log('React props Demo')} />,
document.getElementById('root'));
组件通讯的三种方式
(1)父组件传递数据给子组件
- 父组件提供要传递的state数据
- 给子组件标签添加属性,值为state中的数据
- 子组件中通过props接收父组件中传递的数据
class Parent extends React.Component {
state = {
user: 'cnyangx'
}
render() {
return (
<div className="parent-box" >
parent component:
<Child user={this.state.user}/>
</div>
);
}
}
const Child = (props) => {
return(
<div className="child-box">
child component: 传递过来的数据 user: {props.user}
</div>
)
};
ReactDOM.render(<Parent />, document.getElementById('root'));
(2)子组件传递数据给父组件
- 利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数
- 父组件提供一个回调函数,用来接收数据
- 将该函数作为属性的值,传递给子组件
class Parent extends React.Component {
state = {
getmsg: ''
};
// 提供回调函数用来接收数据
getChildMsg = data => {
this.setState({
getmsg: data
});
console.log(data)
};
render() {
return (
<div className="parent-box" >
parent component: 组件传递过来的数据:{this.state.getmsg}
<Child getMsg = {this.getChildMsg}/>
</div>
);
}
}
class Child extends React.Component{
state = {
user: 'cnyangx'
};
handleClick = () => {
this.props.getMsg(this.state.user)
};
render() {
return(
<div className="child-box">
<button onClick={this.handleClick}>点我传递数据给父组件</button>
</div>
)
}
};
ReactDOM.render(<Parent />, document.getElementById('root'));
(3) 兄弟组件传递
- 将共享状态(数据)提升到最近的公共父组件中,由公共父组件管理这个状态
- 这个称为状态提升
- 公共父组件职责:
1. 提供共享状态
2.提供操作共享状态的方法
- 要通讯的子组件只需要通过props接收状态或操作状态的方法
// 父组件
class Counter extends React.Component {
// 共享的状态
state = {
count: 0
};
// 提供修改状态的方法
onIncrement = () => {
this.setState({
count: this.state.count + 1
})
};
render() {
return (
<div>
<Child1 count={this.state.count} />
<Child2 onIncrement={this.onIncrement}/>
</div>
)
}
}
const Child1 = (props) => {
return <h1>计数器:{props.count}</h1>
};
const Child2 = (props) => {
return <button onClick={() => props.onIncrement()}> child + 1 </button>
};
ReactDOM.render(<Counter />, document.getElementById('root'));
Context -- 跨组件传递数据
// 1. 创建Context 得到两个组件
const { Provider, Consumer } = React.createContext();
// 2. 使用Provider组件作为父节点
class Parent extends React.Component {
render() {
return (
// 3. 设置value属性,表示要传递的数据
<Provider value="要传递的数据">
<div className="parent-box">
<Node/>
</div>
</Provider>
)
}
}
const Node = props => {
return (
<div className="child-box">
<SubNode/>
</div>
)
};
const SubNode = props => {
return (
<div className="grandchild-box">
{/*// 4. 哪一层想要接收数据,就用Consumer进行包裹,在里面回调函数中的参数就是传递过来的值*/}
<Consumer >
{/* 更新:Consumer里面只能有一个根组件 */}
{ data => <span>最后的子节点:{data} </span>}
</Consumer>
</div>
)
ReactDOM.render(<Parent />, document.getElementById('root'));
Props 探究
children属性
- children属性: 表示组件标签的子节点,当组件标签有子节点时,props就会有该属性
- children属性与普通的props一样,值可以使任意值(文本、react元素、组件、甚至是函数)
const Parent = (props) => {
console.log(props);
return (
<div>parent
{props.children}
</div>
)
};
ReactDOM.render(<Parent>
<h1>children</h1>
<p>txt</p>
</Parent>, document.getElementById('root'));
props校验
- 对于组件来说,props是外来的,无法保证组件使用者传入什么格式的数据,简单来说就是组件调用者可能不知道组件封装着需要什么样的数据
- 如果传入的数据不对,可能会导致报错
- 关键问题:组件的使用者不知道需要传递什么样的数据
- props校验:允许在创建组件的时候,指定props的类型、格式等
- 作用:捕获使用组件时因为props导致的错误,给出明确的错误提示,增加组件的健壮性
使用步骤
- 安装包
prop-types (yarn add prop-types | npm i props-types)
- 导入prop-types 包
- 使用
组件名.propTypes={}
来给组件的props添加校验规则 - 校验规则通过PropTypes对象来指定
// props 校验
const Verify = props => {
const arr = props.colors;
const lis = arr.map((item, index) => <li key={index}>{item}</li>);
return (
<ul>{lis}</ul>
)
};
// 添加校验
Verify.propTypes = {
colors: PropTypes.array
};
ReactDOM.render(<Verify colors={['blue', 'yellow', 'red']} />, document.getElementById('root'));
常见的约束规则
创建的类型:
array、bool、func、number、object、string
React元素类型:
element
必填项:
isRequired
特定结构的对象:
shape({})
更多的约束规则
// 添加props校验
// 属性 a 的类型: 数值(number)
// 属性 fn 的类型: 函数(func)并且为必填项
// 属性 tag 的类型: React元素(element)
// 属性 filter 的类型: 对象({area: '上海', price: 1999})
Verify.propTypes = {
colors: PropTypes.array,
a: PropTypes.number,
fn: PropTypes.func.isRequired,
tag: PropTypes.element,
filter: PropTypes.shape({
area: PropTypes.string,
price: PropTypes.number
})
};
ReactDOM.render(<Verify colors={['blue', 'yellow', 'red']} />, document.getElementById('root'));
props的默认值
- 场景:分页组件 -> 每页显示条数
// props 默认值
const DefaultValue = props => {
console.log(props);
return (
<div>
<h1>props默认值: {props.pageSize}</h1>
</div>
)
};
DefaultValue.defaultProps = {
pageSize: 123
};
ReactDOM.render(<DefaultValue />, document.getElementById('root'));
React -- 3/100 】组件通讯的更多相关文章
- React 组件通讯
React 父→子组件通讯 在父组件中子组件上 绑定一个 变量名={要传递的数据}:走我们去子组件中接收.... 直接用 this.props.刚刚起的变量名就ok了 上代 ...
- 【React -- 5/100】 组件复用
组件复用 React组件复用概述 思考:如果两个组件中的部分功能相似或相同,该如何处理? 处理方式:复用相似的功能 复用什么? state 操作state的方法 两种方式: render props模 ...
- React jQuery公用组件开发模式及实现
目前较为流行的react确实有很多优点,例如虚拟dom,单向数据流状态机的思想.还有可复用组件化的思想等等.加上搭配jsx语法和es6,适应之后开发确实快捷很多,值得大家去一试.其实组件化的思想一直在 ...
- React Native的组件ListView
React Native的组件ListView类似于iOS中的UITableView和UICollectionView,也就是说React Native的组件ListView既可以实现UITableV ...
- 【Vue】Vue中的父子组件通讯以及使用sync同步父子组件数据
前言: 之前写过一篇文章<在不同场景下Vue组件间的数据交流>,但现在来看,其中关于“父子组件通信”的介绍仍有诸多缺漏或者不当之处, 正好这几天学习了关于用sync修饰符做父子组件数据双向 ...
- WEB通知和React Native之即时通讯(iOS Android)
WEB通知和React Native之即时通讯(iOS Android) 一,需求分析 1.1,允许服务器主动发送信息给客户端,客户端能监听到并且能接收. 1.2,为了方便同一个系统内的用户可以指定某 ...
- 函数式编程与React高阶组件
相信不少看过一些框架或者是类库的人都有印象,一个函数叫什么creator或者是什么什么createToFuntion,总是接收一个函数,来返回另一个函数.这是一个高阶函数,它可以接收函数可以当参数,也 ...
- React高阶组件 和 Render Props
高阶组件 本质 本质是函数,将组件作为接收参数,返回一个新的组件.HOC本身不是React API,是一种基于React组合的特而形成的设计模式. 解决的问题(作用) 一句话概括:功能的复用,减少代码 ...
- vue 组件通讯方式到底有多少种 ?
前置 做大小 vue 项目都离不开组件通讯, 自己也收藏了很多关于 vue 组件通讯的文章. 今天自己全部试了试, 并查了文档, 在这里总结一下并全部列出, 都是简单的例子. 如有错误欢迎指正. 温馨 ...
随机推荐
- 使用 nodejs 和 axios 以及 cherrio 爬取天气预报
安装依赖 引入依赖 发送请求 解析请求的返回值 以下代码可以复制直接运行,获得 7 天的天气预报 const axios = require('axios') const cheerio = requ ...
- 也谈HTTP协议
HTTP(HyperText Transfer Protocol,超文转移协议,超文本传输协议的译法并不严谨.) 一.网络基础 TCP/IP 1.1 TCP/IP 协议族 TCP/IP 协议族是互联网 ...
- for循环,foreach, map,reduce用法对比+for in,for of
for不做赘述,相当简单: foreach方法: forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数. 注意: forEach() 对于空数组是不会执行回调函数的. array.f ...
- [CSP-S模拟测试]:格式化(贪心)
题目传送门(内部题105) 输入格式 每组数据第一行一个正整数$n$,表示硬盘块数,接下来$n$行,每行两个正整数,第一个正整数为硬盘格式化前的容量,第二个正整数为格式化之后的容量. 输出格式 对每组 ...
- spring boot redis session
1. pom.xml 这里 spring parent的版本 2.1.5会报错 2.1.0和2.1.4经过测试正常 <?xml version="1.0" encoding= ...
- WIN10下安装Linux子系统并安装xface4界面
WIN10下安装Linux子系统并安装xface4界面,使用win10自带的远程桌面工具登陆成功. 成功截图: 安装步骤 1.安装[适用于Linux的Windows子系统]组件 2.win10应用商店 ...
- 省市区,级联查询,ajaxgird,ajaxfrom
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- 2014过去了,正式步入职场了,.net
一.第一家公司(北京XXXXXXX) 从2014年7月1号拿到学位证,到7月15号到北京,努力找工作,用了两个多礼拜,终于找到了一个只有三个人的公司,愿意要我,薪资是实习三千,转正四千. 2014年7 ...
- 2、node-webkit运行web应用,node-webkit把web应用打包成桌面应用
下面我通过一个简单的demo来介绍怎么样把一个web应用打包成一个可执行文件(这里只介绍windows环境) 首先新建一个index.html文件,作为我们这个demo的入口页面,我们暂且就把这个页面 ...
- Git - grafted 和 shallow update not allowed
一般人对开源的模板进行修改是总会进行这样的一条龙操作 # 克隆最近一次提交 git clone xxx --depth 1 # 修改修改修改 提交提交提交 vim xxx git commit -am ...