技术标签: 跨组件通信 react.js context javascript ecmascript
在开发过程中,我们会经常遇到需要组件之间相互进行通信:
- 比如App可能使用了多个Header,每个地方的Header展示的内容不同,那么我们就需要使用者传递给Header一些数据,让其进行展示;
- 又比如我们在Main中一次性请求了Banner数据和ProductList数据,那么就需要传递给他们来进行展示;
- 也可能是子组件中发生了事件,需要由父组件来完成某些操作,那就需要子组件向父组件传递事件;
总之,在一个React项目中,组件之间的通信是非常重要的环节; 父组件在展示子组件,可能会传递一些数据给子组件:
父组件通过 属性=值 的形式来传递给子组件数据;
子组件通过 props 参数获取父组件传递过来的数据;
对于传递给子组件的数据,有时候我们可能希望进行验证,特别是对于大型项目来说:
更多的验证方式,可以参考官网:https://zh-hans.reactjs.org/docs/typechecking-with-proptypes.html
如果没有传递,我们希望有默认值呢?
某些情况,我们也需要子组件向父组件传递消息:
将计数器案例进行拆解;
import React, {
PureComponent} from 'react';
class CounterButton extends PureComponent {
constructor(props) {
super(props);
}
render() {
return (
<button onClick={
e => this.counterIncrement()}>CounterButton里的+1</button>
)
}
counterIncrement() {
const {
increment} = this.props
increment()
// this.props.increment()
}
}
class App extends PureComponent {
constructor(props) {
super(props);
this.state = {
counter: 0
}
}
render() {
return (
<div>
<h2>当前计数: {
this.state.counter}</h2>
<button onClick={
e => this.increment()}>App里的+</button>
<br/>
<CounterButton increment={
e => this.increment()} />
</div>
);
}
increment() {
this.setState({
counter: this.state.counter + 1
})
}
}
export default App ;
import React, {
Component } from 'react';
function ProfileHeader (props) {
return (
<div>
<h2>用户昵称: {
props.nickname}</h2>
<h2>用户等级: {
props.level}</h2>
</div>
)
}
function Profile (props) {
return (
<div>
{
/* <ProfileHeader nickname={props.nickname} level={props.level} /> */}
<ProfileHeader {
...props} />
<ul>
<li>设置1</li>
<li>设置2</li>
<li>设置3</li>
<li>设置4</li>
</ul>
</div>
)
}
class App extends Component {
constructor(props) {
super(props)
this.state = {
nickname: 'zepp',
level: 99
}
}
render() {
const {
nickname, level} = this.state
return (
<div>
app
<Profile nickname={
nickname} level={
level} />
</div>
);
}
}
export default App;
非父子组件数据的共享:
但是,如果层级更多的话,一层层传递是非常麻烦,并且代码是非常冗余的:
什么时候使用Context.Consumer呢?
import React, {
Component} from 'react';
// 创建Context对象
const UserContext = React.createContext({
nickname: 'bbb',
level: -1
})
/* function ProfileHeader (props) {
return (
<div>
<h2>用户昵称: </h2>
<h2>用户等级: </h2>
</div>
)
} */
class ProfileHeader extends Component {
render() {
console.log('====================================');
console.log(this.context);
console.log('====================================');
return (
<div>
<h2>用户昵称:{
this.context.nickname} </h2>
<h2>用户等级:{
this.context.level} </h2>
</div>
)
}
}
ProfileHeader.contextType = UserContext
function Profile(props) {
return (
<div>
{
/* <ProfileHeader nickname={props.nickname} level={props.level} /> */}
<ProfileHeader/>
<ul>
<li>设置1</li>
<li>设置2</li>
<li>设置3</li>
<li>设置4</li>
</ul>
</div>
)
}
class App extends Component {
constructor(props) {
super(props)
this.state = {
nickname: 'zepp222',
level: 99
}
}
render() {
const {
nickname, level} = this.state
return (
<div>
app
<UserContext.Provider value={
this.state}>
<Profile/>
</UserContext.Provider>
</div>
);
}
}
export default App;
import React, {
Component} from "react";
// 创建Context对象
const UserContext = React.createContext({
nickname: "bbb",
level: -1,
});
function ProfileHeader(props) {
return (
<UserContext.Consumer>
{
(value) => {
return (
<div>
<h2>用户昵称:{
value.nickname} </h2>
<h2>用户等级:{
value.level} </h2>
</div>
);
}}
</UserContext.Consumer>
);
}
/* class ProfileHeader extends Component {
render() {
console.log('====================================');
console.log(this.context);
console.log('====================================');
return (
<div>
<h2>用户昵称:{this.context.nickname} </h2>
<h2>用户等级:{this.context.level} </h2>
</div>
)
}
} */
// ProfileHeader.contextType = UserContext;
function Profile(props) {
return (
<div>
<ProfileHeader/>
<ul>
<li>设置1</li>
<li>设置2</li>
<li>设置3</li>
<li>设置4</li>
</ul>
</div>
);
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
nickname: "zepp",
level: 99,
};
}
render() {
return (
<div>
app
<UserContext.Provider value={
this.state}>
<Profile/>
</UserContext.Provider>
</div>
);
}
}
export default App;
import React, {
Component } from "react";
// 创建Context对象
const UserContext = React.createContext({
nickname: "bbb",
level: -1,
});
const ThemeContext = React.createContext({
color: "black",
});
function ProfileHeader(props) {
return (
<UserContext.Consumer>
{
(value) => {
return (
<ThemeContext.Consumer>
{
(theme) => {
return (
<div>
<h2>用户昵称:{
value.nickname} </h2>
<h2>用户等级:{
value.level} </h2>
<h2>颜色: {
theme.color}</h2>
</div>
);
}}
</ThemeContext.Consumer>
);
}}
</UserContext.Consumer>
);
}
/* class ProfileHeader extends Component {
render() {
console.log('====================================');
console.log(this.context);
console.log('====================================');
return (
<div>
<h2>用户昵称:{this.context.nickname} </h2>
<h2>用户等级:{this.context.level} </h2>
</div>
)
}
} */
ProfileHeader.contextType = UserContext;
function Profile(props) {
return (
<div>
<ProfileHeader />
<ul>
<li>设置1</li>
<li>设置2</li>
<li>设置3</li>
<li>设置4</li>
</ul>
</div>
);
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
nickname: "zepp",
level: 99,
};
}
render() {
return (
<div>
app
<UserContext.Provider value={
this.state}>
<ThemeContext.Provider value={
{
color: "red" }}>
<Profile />
</ThemeContext.Provider>
</UserContext.Provider>
</div>
);
}
}
export default App;
文章浏览阅读183次。前言作为一个iOS开发者,我觉得对于JavaScript入门还是并不是太困难,当然了,这只是入门而已,我们就从入门开始搞事.JavaScript的开始JavaScript作为一种轻量级的脚本语言,JavaScript是不会做类似于OC预编译的工作,我们需要把代码放入** <p id = 'label'>HelloWorld</p>然后我们在** <script > document.getElementById("label").innerH.._js 有跟oc一样的extension类别吗
文章浏览阅读211次。它的核心思想是将待排序的元素按照大小映射到一个计数数组中,并根据计数数组的结果重新排列原数组。计数排序算法的主要优点是稳定、快速、简单易懂,适用于大量数据范围较小的排序任务。接下来,程序通过循环遍历原数组,计算每个元素在序列中出现的次数,并将其存入对应的计数数组位置中。然后,程序累加计算每个元素在排好序的序列中的位置,根据计数数组重新排列原数组,最后返回排好序的新数组。总之,计数排序算法是一种高效、易于理解和实现的线性时间复杂度排序算法,特别适用于大规模数据范围较小的排序任务。,并首先找到数组中的最大值。_python 计数后按照个数排序
文章浏览阅读729次。visdom的安装排坑及远程启动visdom安装排坑visdom首次启动自动下载文件,种种原因导致下载往往失败,需要做一下处理:(1) 将'.../Anaconda/Anaconda/Lib/site-packages/visdom/server.py’的1917行注释掉(2) '.../Anaconda/Anaconda/Lib/site-packages/visdom/static’替换为[link](https://download.csdn.net/download/qq_35878757/_visdom 1917行注释
文章浏览阅读564次,点赞2次,收藏10次。CC, color conversion,色彩转换CC, color correction,色彩矫正CE, chroma enhancement,色度增强SNR,signal-to-noise ratio,信噪比SNR, skin noise reduce,肤色降噪STD, standard deviation,标准差OIS, optical image stabilization 光学稳像 PDAF,phase detection auto focus,相位对焦CPP: camera po_高通hjr是什么意思
文章浏览阅读1.3w次,点赞4次,收藏26次。原文:http://blog.csdn.net/wemedia/details.html?id=43211深度学习哪家强?吴恩达、Udacity和Fast.ai的课程我们替你分析好了原2017.08.20AI科技大本营翻译 | AI科技大本营(rgznai100)参与 | reason_W 引言_ai 深度学习
文章浏览阅读5.8k次。异步赠书:Kotlin领衔10本好书 SDCC 2017之区块链技术实战线上峰会 程序员9月书讯 每周荐书:Java Web、Python极客编程(评论送书) window.quickReplyflag = true; var isBole = false; var fasrc="htt_小波包能量的matlab代码
文章浏览阅读7k次。原文链接:https://www.lianxh.cn/news/547c05d012a2d.html目录1. GARCH 模型介绍 2. DCC-MGARCH 基本原理 3. 软件实现 3.1 R 语言命令 3.2 Stata 命令 4. DCC-MGARCH 模型的应用 5. 参考文献1. GARCH 模型介绍简单地说,多元 GARCH 指的是多个时间序列之间各自波动的交互影响,这里的波动具体指的是建立时间序列 ARIMA 或 VAR 模型后,提取到的各时间序列残差的波_dcc garch stata
文章浏览阅读1k次,点赞10次,收藏25次。毕业设计:基于深度学习的预约调度算法的电梯群控系统通过深度学习模型对乘客的出行数据进行学习,预测未来的电梯使用需求,并据此优化电梯的调度策略。为计算机毕业设计提供了一个创新的方向,结合了深度学习和计算机视觉技术,为毕业生提供了一个有意义的研究课题。对于计算机专业、软件工程专业、人工智能专业、大数据专业的毕业生而言,提供了一个具有挑战性和创新性的研究课题。无论您对深度学习技术保持浓厚兴趣,还是希望探索机器学习、算法或人工智能的领域的同学,能为您提供灵感和指导;_基于深度学习的电梯智能监控系统研究与设计
文章浏览阅读217次。下载v1.6版本,刚开始我还没找到,后面对照别人的截图才找到(哈哈,感觉自己好二),把鼠标移过去,这个地方是才从黑变成这个绿色。_freemodbus源码下载
文章浏览阅读2.8w次,点赞49次,收藏230次。 对于pytorch保存网络参数,大家一般可以看到有 .pkl文件 以及 .pth文件,对于这两者有什么区别,以及如何保存网络参数等,本文就好好讲述一下。 一、保存方式 首先我们知道不论是保存模型还是参数都需要用到torch.save()。_pytorch保存网络结构
文章浏览阅读1.2w次,点赞12次,收藏21次。yolov8遇到报错_modulenotfounderror: no module named 'ultralytics
文章浏览阅读961次,点赞20次,收藏24次。LeetCode刷题笔记;算法题:接雨水;核心思想是利用双指针在O(1)空间复杂度下解决【接雨水】问题。【双指针】【python】【困难】