05 proxy代理、组件间的通信

React全家桶

一、脚手架配置代理(proxy)的方式

CORS:

请求url:http://www.baidu.com
发送url:http://www.jd.com
response.setHeader('Access-Control-Allow-Origin','*');

在这里插入图片描述

  • 通过express快速搭建一个服务

  • 创建一个图书组件

import React, { useEffect } from 'react'
import axios from 'axios'
export default function Books() {//在组件挂载完成之后,相当于ComponentDidMount()方法,进行ajax请求useEffect(() => {//ajax请求async function main() {let result = await axios.get('http://127.0.0.1:5000/books');console.log(result)}main();}, [])return (<div>Books</div>)
}
  • 在package.json文件中添加一行配置
"proxy":"http://127.0.0.1:5000"
  • 重启服务 这一步非常重要
  • 修改请求的url地址
async function main() {let result = await axios.get('/books');console.log(result)
}
main();
  • 但是这种方式相对单一,只能配置一个代理,如果想要配置多个代理,这就不行了
  • 解决办法:需要在src的根目录中创建一个setupProxy.js文件,注意文件名不能修改
    • 安装一个包:npm i http-proxy-middleware
//1、导包
const proxy = require('http-proxy-middleware');
//2、导出一个方法
module.exports = function (app) {app.use(proxy.createProxyMiddleware('/api', {//请求的目的地址target: 'http://127.0.0.1:5000',//控制服务器收到的请求头中Host的值changeOrigin: true,//重写路径pathRewrite: {'^/api': ''}}))
}
  • 修改代码
import React, { useEffect, useState } from 'react'
import axios from 'axios'
export default function Books() {let [booklist, setBookList] = useState([]);useEffect(() => {//ajax请求async function main() {let result = await axios.get('/api/books');if (result.status >= 200 && result.status < 300) {setBookList(result.data)}}main();}, [])return (<div><h3>图书列表</h3><hr /><ul>{booklist.map(item => {return <li key={item.id}>{item.name}</li>})}</ul></div>)
}
  • 再次基础之上添加模糊搜索功能
  • Book.jsx
import React, { useState } from 'react'
import Header from './Header/Header'
import Main from './Main/Main'
import axios from 'axios'
export default function Books() {let [booklist, setBookList] = useState([]);let searchBookList = async (v) => {let result = await axios.get('/api/books', {params: {name: v}});setBookList(result.data)}return (<div><h3>图书列表</h3><hr /><Header searchBookList={searchBookList} /><Main booklist={booklist} /></div>)
}

Header.jsx

import React, { useRef } from 'react'export default function Header(props) {let { searchBookList } = props;let bookname = useRef();let searchBook = () => {//获取文本框中的数据let book = bookname.current.value;if (book === '') {alert('请输入书名');return;}searchBookList(book)//清空文本框中的数据bookname.current.value = ''}return (<div>请输入图书名称:<input type="text" ref={bookname} /> &nbsp;<button onClick={searchBook}>搜索</button></div>)
}

Main.jsx

import React from 'react'export default function Main(props) {let { booklist } = props;return (<ul>{booklist.map(item => {return <li key={item.id}>{item.name}</li>})}</ul>)
}

二、组件间的通信

react中的组件间的通信有三种:父子间、兄弟间、祖孙间

2.1 父子间组件通讯(props)

2.1.1 父->子

直接通过props属性向子组件传递数据,可以是一般的纯数据 <子组件 num={20}/>

也可以是父组件中的状态数据,当父组件中的状态数据更改,也会影响到子组件

2.1.2 子->父

默认情况下子是被动接收数据的一方,是没有办法直接修改父组件中的数据,但是如果父组件传递一个可以修改父

组件的状态数据的方法,通过props的形式给子组件,那么子组件修改的值是可以 影响父组件中的状态数据

2.2 祖孙间(任意后代)组件通讯(context)

在这里插入图片描述

2.2.1 祖-> 孙

  • 调用 React. createContext() 创建 context 对象 【谁主动传递数据,就在谁的身上添加这个对象】
const context = React.createContext() 
  • 外部组件中使用 context 上的 Provider 组件作为父节点, 使用value属性定义要传递的值
<context.Provider value={要传递的值}>  提供数据<div className="App"> <Child1 /> </div> 
</context.Provider>
  • 孙组件中导入祖组件
import { context } from '../GrandFather/GrandFather'
  • 孙组件接收祖组件传递的数据
  • 方式1:利用Hook钩子函数中的useContext方法接收传递的数据
import React, { useContext } from 'react'
let name = useContext(context);
console.log(name);
  • 方式2:利用context 上的 Consumer组件作为父节点,在其中使用{}添加回调函数写法
import React from 'react'
import { context } from '../GrandFather/GrandFather'
export default function Son() {return (<div style={{ width: 400, height: 200, border: '1px dashed green' }}><context.Consumer>{name => <p>姓名:{name}</p>  #name可以自定义,表示提供者提供的value数据}</context.Consumer></div>)
}

2.2.2 孙->祖

  • 将祖组件中的数据做成状态数据,然后将初始状态数据以及修改状态数据通过value一并传递给孙组件
  • 孙组件接收并进行修改

例如:将GrandFather组件中的数据传递给Son组件

在这里插入图片描述

GrandFather.jsx

import React, { createContext, useState } from 'react'
import Father from '../Father/Father'
export let context = createContext();
export default function GrandFather() {// let name = '李四'let [name, setName] = useState('李四');let [age, setAge] = useState(20)return (<div style={{ width: 400, height: 400, border: '1px dashed #ccc' }}><h4>GrandFather组件</h4><p>姓名:{name}</p><p>年龄:{age}</p><hr /><context.Provider value={[name, setName, age, setAge]}><Father /></context.Provider></div>)
}

Father.jsx

import React, { useContext } from 'react'
import Son from '../Son/Son'
import { context } from '../GrandFather/GrandFather'
export default function Father(props) {// let { age, changeAge } = props;let result = useContext(context);console.log(result)let updateAge = (num) => {return () => {// changeAge(20)result[3](result[2] + num);}}return (<div style={{ width: 400, height: 300, border: '1px dashed red' }}><h4>Father组件</h4><span>年龄:{result[2]}</span><hr /><button onClick={updateAge(100)}>更新年龄</button><hr /><Son /></div>)
}

Son.jsx

// import React, { useContext } from 'react'
import { context } from '../GrandFather/GrandFather'
export default function Son() {// let name = useContext(context);let changeName = (f) => {f('王五');}return (<context.Consumer>{value => (<div style={{ width: 400, height: 200, border: '1px dashed green' }}><h4>Son组件</h4><p>姓名:{value[0]}</p><button onClick={e => changeName(value[1])}>修改姓名</button></div >)}</context.Consumer>)
}

一般应用中不使用, 但一些插件库内部会使用context封装, 如: react-redux

2.3 兄弟间组件通讯(pub/sub)

注意:兄弟间的组件是非嵌套式写法的组件

在这里插入图片描述

发布订阅机制: publish(发布者) / subscribe(接受者)

pubsub-js是一个用JS编写的库。

利用订阅发布模式, 当一个组件的状态发生了变化,可以通知其他任意组件更新这些变化

  • 安装:
npm install pubsub-js
  • 导入
import PubSub from "pubsub-js" // 导入的PubSub是一个对象.提供了发布/订阅的功能
  • 发送消息的组件调用
PubSub.publish('频道名称','值');
  • 接收消息的组件中调用
PubSub.subscribe('频道名称',(msg,data)=>{//回调函数中的第一个参数:频道名称//回调函数中的第二个参数:值console.log(msg);console.log(data);
});
  • 取消订阅
PubSub.unsubscribe('频道名称');

A.jsx

import React from 'react'
import B from '../B/B'
import C from '../C/C'export default function A() {return (<div><B /><C /></div>)
}

B.jsx

import React from 'react'
import PubSub from 'pubsub-js'
export default function B() {let sendData = () => {PubSub.publish('keywords', '张三丰');}return (<div style={{ width: 400, height: 100, border: '1px dashed #ccc' }}><h4>我是B组件</h4><button onClick={sendData}>C组件发送数据</button></div>)
}

C.jsx

import React, { useEffect, useState } from 'react'
import PubSub from 'pubsub-js'
export default function C() {let [name, SetName] = useState('')useEffect(() => {PubSub.subscribe('keywords', (msg, data) => {SetName(data);});return () => {PubSub.unsubscribe('keywords');}}, [])return (<div style={{ width: 400, height: 150, border: '1px dashed red' }}><h3>我是C组件</h3><p>姓名:{name}</p></div>)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/190.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用OpenXML库替换docx文档(Word文档)中的特定字段

在批量生成Word文档的应用中&#xff0c;最常见的需求莫过于替换掉文档中的特定字段以生成新的文档。利用OpenXML库可轻松实现这一需求。 不完善版本 首先放出最简单然而有bug的版本&#xff1a; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Wor…

Spring Boot 中的事务回滚规则

Spring Boot 中的事务回滚规则 在应用程序中&#xff0c;事务管理是一个重要的概念。事务是指一系列的操作&#xff0c;这些操作要么全部成功&#xff0c;要么全部失败。在Spring Boot中&#xff0c;我们可以使用事务管理器来管理事务。在使用事务管理器的时候&#xff0c;一个…

【Oracle】springboot连接Oracle 集成mybatis、druid

目录 项目结构与库表数据pom.xmlapplication.yml实体类Mappercontroller接口测试 基于spring-boot 2.7.11&#xff0c;连接Oracle 11g 仅做一个简单的示例 特别说明&#xff08;不一定正确&#xff0c;还请指正&#xff09;&#xff1a;我Oracle也不熟&#xff0c;但据我观察发…

Grafana任意文件读取漏洞(CVE-2021-43798)

Grafana任意文件读取漏洞&#xff08;CVE-2021-43798&#xff09; 一、漏洞描述 Grafana是一个跨平台、开源的数据可视化网络应用程序平台。用户配置连接的数据源之后&#xff0c;Grafana可以在网络浏览器里显示数据图表和警告。 二、漏洞影响范围 影响版本&#xff1a; Gr…

【资料分享】全志科技T507-H评估板规格书(4核ARM Cortex-A53,主频1.416GHz)

1 评估板简介 创龙科技TLT507-EVM是一款基于全志科技T507-H处理器设计的4核ARM Cortex-A53国产工业评估板&#xff0c;主频高达1.416GHz&#xff0c;由核心板和评估底板组成。核心板CPU、ROM、RAM、电源、晶振等所有器件均采用国产工业级方案&#xff0c;国产化率100%。同时&a…

ElasticSearch 8.0+ 版本Windows系统启动

下载地址&#xff1a;https://www.elastic.co/cn/downloads/past-releases/winlogbeat-8-8-1 解压\elasticsearch\elasticsearch-8.5.1 进入bin目录&#xff0c;启动elasticsearch.bat 问题1&#xff1a; warning: ignoring JAVA_HOMED:\jdk1.8.0_271; using bundled JDK J…

FlutterUnit 已上架 iOS,暗色模式全面支持

theme: cyanosis 一、FlutterUnit 的全平台支持 FlutterUnit 是我的一个开源项目&#xff0c;基于 Flutter 构建的一个 全平台 应用程序。现在很荣幸地宣布: FlutterUnit 已经上架 iOS 的 App Store &#xff0c;自此主流的几大平台均已提供体验。 项目地址: https://github.co…

普通人如何居家办公实现网上赚钱?分享五种互联网赚钱的副业项目

科思创业汇 大家好&#xff0c;这里是科思创业汇&#xff0c;一个轻资产创业孵化平台。赚钱的方式有很多种&#xff0c;我希望在科思创业汇能够给你带来最快乐的那一种&#xff01; 网上赚钱&#xff0c;主要是利用各种信息差异从网上获取收入。 近年来&#xff0c;随着互联网…

分布式存储Ceph的部署及应用(创建MDS、RBD、RGW 接口)

系列文章目录 文章目录 系列文章目录一、1.存储基础2. 单机存储的问题3. 分布式存储&#xff08;软件定义的存储 SDS&#xff09; 二 Ceph1.Ceph 简介2. Ceph 数据的存储过程 总结 一、 1.存储基础 1.1 单机存储设备 ●DAS&#xff08;直接附加存储&#xff0c;是直接接到计算…

【Linux】文件基础IO操作:C语言接口 | 系统调用接口 | 重定向

重修C语言文件知识Linux文件知识标记位传参文件的系统调用理解什么是文件文件fd的分配规则重定向C语言文件层面的缓冲区知识 重修C语言文件知识 打开文件操作fopen函数&#xff1a; 我们看一段代码&#xff0c;以写(w)的形式来打开文件&#xff1a; #include <stdio.h>…

在Mac上安装Aspectj1.9.8(用于Java17)+IDEA

1. 确定所使用的Java版本和AspectJ的对应关系 2. 下载AspectJ包 3. 安装AspectJ 4. 添加AspectJ对应的环境变量 5. AspectJ测试-简单终端测试 6. AspectJ测试-通过IDEA敲代码测试 ---------------------------------------详细教程-------------------------------------…

css基础(二)

目录 1. CSS 的复合选择器 1.1 什么是复合选择器 1.2 后代选择器(重要&#xff09; 1.3 子选择器(重要&#xff09; 1.4 并集选择器(重要&#xff09; 1.5 伪类选择器 1.6 链接伪类选择器 1.7 :focus伪类选择器 1.8 复合选择器总结 二、 CSS 的元素显示模式 2.1什么是元素显示模…