05 proxy代理、组件间的通信

news2024/11/17 1:51:16

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.coloradmin.cn/o/700588.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录算法训练营第51天 | 309.最佳买卖股票时机含冷冻期 + 714.买卖股票的最佳时机含手续费 + 股票问题总结

今日任务 目录 309.最佳买卖股票时机含冷冻期 - Medium 714.买卖股票的最佳时机含手续费 - Medium 股票问题总结 309.最佳买卖股票时机含冷冻期 - Medium 题目链接&#xff1a;力扣-309. 最佳买卖股票时机含冷冻期 给定一个整数数组prices&#xff0c;其中第 prices[i] 表…

字节测试工程师总结的自动化测试10个最佳实践

虽然大家都知道坚果是非常健康和有营养的&#xff0c;但是&#xff0c;当你尝试吃它的时候&#xff0c;我猜测过程都不会很顺利。 现实就是那么相似&#xff0c;我们都知道测试自动化对软件开发有好处&#xff08;就像坚果对我们的身体一样&#xff01;&#xff09;&#xff0…

【Redis】Redis五种常用数据类型的使用方法

文章目录 一、String数据类型1. SET/GET/APPEND/STRLEN2. INCR/DECR/INCRBY/DECRBY3. GETSET4. SETEX5. SETNX6. MSET/MGET/MSETNX 二、List数据类型1. LPUSH/LPUSHX/LRANGE2. LPOP/LLEN3. LREM/LSET/LINDEX/LTRIM4. LINSERT5. RPUSH/RPUSHX/RPOP/RPOPLPUSH 三、Hash数据类型&a…

【力扣】DP/贪心:1681. 最小不兼容性

【力扣】DP/贪心&#xff1a;1681. 最小不兼容性 文章目录 【力扣】DP/贪心&#xff1a;1681. 最小不兼容性1. 题目描述2. 解题2.1 不可行2.2 DP&#xff08;预处理 状态压缩 动态规划&#xff09; 参考 1. 题目描述 给你一个整数数组 nums​​​ 和一个整数 k 。你需要将这…

【C++】一文理清C++中的五种强制类型转换

深入理解C中五种强制类型转换的使用场景 一、C风格的强制类型转换 使用形式&#xff1a; Type b (Type)a;C风格的强制类型转换很容易理解&#xff0c;不管什么类型都可以直接进行转换。C也支持C风格的强制类型转换&#xff0c;但是C风格的强制类型转换可能会带来一些隐患&a…

2023.6.29-限定次数的循环操作

首先试着实现一个功能&#xff1a;键入一个整数&#xff0c;然后显示出这个整数个“*”&#xff1a; 代码&#xff1a; int a;printf("请输入一个整数&#xff1a;");scanf("%d",&a);while (a-- > 0)printf("*");printf("\n")…

模拟信号、数字信号

1、模拟信号、模拟电路 1&#xff09;模拟信号 是指连续变化的电信号&#xff0c;比如说话时的声音信号。 模拟信号可以用连续的电压或电流来表示&#xff08; 模拟信号就是电信号&#xff09;数字信号则是用离散的电压或电流来表示&#xff08;0 或 1&#xff09; 2&#x…

ROS:常用命令汇总

目录 一、前言二、rosnode三、rostopic3.1rostopic list3.2rostopic pub3.3rostpic echo3.4rostopic info 四、rosservice4.1rosservice args4.2rosservice call 五、rosmsg5.1rosmsg package5.2rosmsg show 六、rossrv6.1rossrv package6.2rossrv show 七、rosparam7.1rospara…

CSDN | CDC 城市开发者联盟开始招募啦!

一、CDC&#xff08;城市开发者联盟&#xff09;介绍 CDC 是由 CSDN 发起的公益性同城高端开发者社区&#xff0c;全称 City Developers Community&#xff0c;通过在每个城市招募和培养“CDC 城市合伙人”&#xff0c;一起在当地构建“千城千面”的线下开发者社交圈&#xff…

arcserver图层数据导出插件

arcserver数据导出插件使用 下载地址&#xff1a;https://download.csdn.net/download/u011405698/87966050?spm1001.2014.3001.5503 如果需要代码或商业合作请联系公众号&#xff1a;世奇 插件不依赖其他第三方类库&#xff0c;只依赖arcpy&#xff0c;使用简单方便。可以…

C++标准模板库STL (未完)

概述 STLstandard template library是 C 标准库的一部分&#xff0c;无需单独安装&#xff0c;只需#include 头文件 什么是模板&#xff1f;见c面向对象程序设计中模板一节 顺序性容器 vector 向量 变长数组 声明 vector<类型名> 变量名[数组长度];类型名可以是已有…

社交商务时代已经到来,ss客服帮您抓住风口

社交商务时代已经到来&#xff0c;ss客服帮您抓住风口 近年来&#xff0c;社交媒体商务的概念已成为一股强大的力量。通过将社交媒体平台的影响力和影响力与在线购物的便利性相结合&#xff0c;它正在彻底改变企业与客户互动和销售产品或服务的方式。 什么是社交商务&#xf…

MyBatisPlus代码生成器插件

1、下载IDEA插件&#xff1a;MybatisPlus。 2、使用插件生成代码 首先点击IDEA导航菜单上的Other选项&#xff0c;然后进行数据库和代码生成器的配置&#xff1a; 数据库配置&#xff1a; 代码生成器配置&#xff0c;然后点击code generator&#xff1a; 最会插件会按照配置…

Timeout while checking target RAM, RAMCode did not respond in time

问题 使用jlink烧入gd32f450时&#xff0c;jlink提示错误Timeout while checking target RAM, RAMCode did not respond in time; 解决办法 原因是RAM的地址范围错误&#xff0c;默认选择gd32f450vi的ram大小是512k&#xff0c;但是该芯片中的ram并不连续&#xff0c;其中64…

C++ 动态内存

了解动态内存在 C 中是如何工作的是成为一名合格的 C 程序员必不可少的。C 程序中的内存分为两个部分&#xff1a; 栈&#xff1a;在函数内部声明的所有变量都将占用栈内存。堆&#xff1a;这是程序中未使用的内存&#xff0c;在程序运行时可用于动态分配内存。 很多时候&…

【C/C++】类成员函数指针 定义 使用方法

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

使用conda虚拟环境,Jupyter Notebook 链接不上 kernel

1&#xff0c;检查 ipykernel 和 ipython 是否一致 输入pip list 或者conda list检查一下相应库的版本是不一致 不一致的话&#xff0c;可以更新这两个库的版本&#xff1a;pip install --upgrade 库名 2&#xff0c;看控制台的报错&#xff0c;如果是报404&#xff0c;内核找不…

leetcode 145. 二叉树的后序遍历

2023.6.24 继上一题前序遍历&#xff0c;这道后序遍历就很容易了&#xff0c;把递归的顺序稍微改一下就行。 递归法&#xff1a; class Solution { public:void travelsal(TreeNode* cur , vector<int>& ans){if(cur nullptr) return;travelsal(cur->left , an…

如何设计真正高性能高并发分布式系统?

1 、引子 软件复杂性来源于几个方面&#xff1a;高并发高性能、高可用、可扩展、低成本、低规模、可维护、安全等。架构演化、发展都是为了试图降低复杂性&#xff1a; 高并发、高性能&#xff1a;互联网系统特点&#xff0c;用户量大&#xff0c;请求量大&#xff0c;高并发高…

NLP学习笔记(二)

文章目录 &#xff08;一&#xff09;负采样&#xff08;二&#xff09;GloVe1.带全局语料库的跳元模型2.GloVe模型3.问题4.跳元模型与GloVe模型的比较 &#xff08;三&#xff09;问题1.参数初始化2.梯度下降3.下游任务4.句法信息5.似然估计6.词向量表示 &#xff08;一&#…