Blog
首页
文档
收藏
关于
  • 在线转换时间戳 (opens new window)
  • 在线压缩图片 (opens new window)
  • Float-Double转二进制 (opens new window)
  • 文件转Hex字符串 (opens new window)

HiuZing

🍑
首页
文档
收藏
关于
  • 在线转换时间戳 (opens new window)
  • 在线压缩图片 (opens new window)
  • Float-Double转二进制 (opens new window)
  • 文件转Hex字符串 (opens new window)
  • 前端面试题

  • JavaScript

  • Vue2

  • port

  • CSS

  • Node.js

  • JavaScript优化

  • uniapp

  • Mini Program

  • TypeScript

  • 面向对象编程

  • UI组件

  • Plugin

  • Vue3

  • 性能优化

  • Axios

  • 状态管理

  • React

    • 教程

      • React 简介
      • React 组件
      • React 应用
      • React AJAX
        • axios
          • get
          • post
          • react脚手架配置代理
        • 案例—github用户搜索
          • 父子通信
        • 消息订阅-发布机制
          • 概念
          • 过程
          • 案例(消息订阅版)
        • 扩展:Fetch
          • 特点
          • get
          • post
          • 案例(纯发送请求部分)
      • React Router5
      • React Redux
      • React 扩展内容
      • React Router6
      • React Router Hooks
      • React Hooks
    • 实战

  • Mock

  • Icon

  • Template

  • 构建工具

  • 项目规范配置

  • Taro

  • SVG

  • React Native

  • 前端
  • React
  • 教程
HiuZing
2023-05-01
目录

React AJAX

# axios

  1. 封装XmlHttpRequest对象的ajax
  2. promise风格
  3. 可以用在浏览器端和node服务器端

# get

axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response.data);
  })
  .catch(function (error) {
    console.log(error);
  });

axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# post

axios.post('/user', {
  firstName: 'Fred',
  lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
1
2
3
4
5
6
7
8
9
10

# react脚手架配置代理

# 方法一

在package.json中追加如下配置

"proxy":"http://localhost:5000"
1

说明:

  1. 优点:配置简单,前端请求资源时可以不加任何前缀。
  2. 缺点:不能配置多个代理。
  3. 工作方式:上述方式配置代理,当请求了3000不存在的资源时,那么该请求会转发给5000 (优先匹配前端资源)

# 方法二

  1. 第一步:创建代理配置文件

    src/setupProxy.js
    
    1
  2. 安装

    npm i http-proxy-middleware
    
    
    1
    2
  3. 编写配置具体代理规则:

    const {createProxyMiddleware} = require('http-proxy-middleware')
    
    module.exports = function(app) {
        //api1是需要转发的请求(所有带有/api1前缀的请求都会转发给5000)
        app.use('/api1', createProxyMiddleware({
            target: 'http://localhost:5000', //配置转发目标地址(能返回数据的服务器地址)
            changeOrigin: true, //控制服务器接收到的请求头中host字段的值
            pathRewrite: {'^/api1': ''} //去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)
        }))
        
    	app.use('/api2', createProxyMiddleware({
        	target: 'http://localhost:5001',
    	    changeOrigin: true,
        	pathRewrite: {'^/api2': ''}
    	  }))
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

笔记

  • changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
  • changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000
  • changeOrigin默认值为false,但我们一般将changeOrigin值设为true

说明:

  1. 优点:可以配置多个代理,可以灵活的控制请求是否走代理。
  2. 缺点:配置繁琐,前端请求资源时必须加前缀。

# 案例—github用户搜索

# 父子通信

    import React, {Component} from 'react';
    import Search from "./components/Search";
    import List from "./components/List";
    
    class App extends Component {
      state = {
        users: [], // 初始化状态,users初始值为数组
        isFirst: true, // 是否为第一次打开页面
        isLoading: false, // 标识是否处于加载中
        err: '' // 存储请求相关的错误信息
      }
      // 更新App的state(子组件给父组件传参,需父组件定义一个函数,子组件必要时调用函数)
      updateAppState = (stateObj) => {
        this.setState(stateObj)
      }
      render() {
        return (
          <div className="container">
            <Search updateAppState={this.updateAppState}/>
            <List {...this.state}/>
          </div>
        );
      }
    }
    export default App;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    import React, {Component} from 'react';
    import axios from "axios";
    
    class Search extends Component {
      search = () => {
        // 获取用户的输入
        // 结构赋值连续写法
        const {keyWordElement: {value: keyword}} = this
        // 发送请求前通知App更新状态
        this.props.updateAppState({isFirst: false, isLoading: true})
        // 发送网络请求
        axios.get(`http://localhost:3000/api1/search/users?q=${keyword}`).then(
          response => {
            // 请求成功后通知App更新状态
            this.props.updateAppState({isLoading: false, users: response.data.items})
          },
          error => {
            // 请求失败后通知App更新状态
            this.props.updateAppState({isLoading: false, err: error.message})
          }
        )
      }
      render() {
        return (
          <section className="jumbotron">
            <h3 className="jumbotron-heading">Search Github Users</h3>
            <div>
              <input ref={c => this.keyWordElement = c} type="text" placeholder="enter the name you search"/>&nbsp;
              <button onClick={this.search}>Search</button>
            </div>
          </section>
        );
      }
    }
    
    export default Search;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    import React, {Component} from 'react';
    import './index.css'
    
    class List extends Component {
    render() {
      const {users, isFirst, isLoading, err} = this.props
      return (
        <div className="row">
          {
            isFirst ? <h2>欢迎使用,输入关键字随后搜索</h2> :
              isLoading ? <h2>Loading...</h2> :
                err ? <h2>{err}</h2> :
                  users.map((userObj) => {
                    return (
                      <div className="card" key={userObj.id}>
                        <a rel="noreferrer" href={userObj.html_url} target="_blank">
                          <img alt="avatar" src={userObj.avatar_url} style={{width: '100px'}}/>
                        </a>
                        <p className="card-text">{userObj.login}</p>
                      </div>
                    )
                  })
          }
        </div>
      );
    }
    }
    export default List;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    // Make sure to add code blocks to your code group

    笔记

    // ES6小知识点:解构赋值+重命名
    let obj = {a:{b:1}}
    const {a} = obj; //传统解构赋值
    const {a:{b}} = obj; //连续解构赋值
    const {a:{b:value}} = obj; //连续解构赋值+重命名
    
    1
    2
    3
    4
    5

    # 消息订阅-发布机制

    # 概念

    1. 先订阅,再发布(理解:有一种隔空对话的感觉)
    2. 适用于任意组件间通信
    3. 要在组件的componentWillUnmount中取消订阅

    # 过程

    1.工具库: PubSubJS

    2.下载: npm install pubsub-js --save

    3.使用:

    ​ 1)import PubSub from 'pubsub-js' //引入

    ​ 2)PubSub.subscribe('delete', function(msg,data){ }); //订阅

    ​ 3)PubSub.publish('delete', data) //发布消息

    ​ 4)PubSub.unsubscribe(this.token) //取消订阅

    # 案例(消息订阅版)

    基于以上案例修改

      import React, { Component } from 'react'
      import Search from './components/Search'
      import List from './components/List'
      
      export default class App extends Component {
      	render() {
      		return (
      			<div className="container">
      				<Search/>
      				<List/>
      			</div>
      		)
      	}
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      import React, { Component } from 'react'
      import PubSub from 'pubsub-js'
      import axios from 'axios'
      
      export default class Search extends Component {
      	search = ()=>{
      		//获取用户的输入(连续解构赋值+重命名)
      		const {keyWordElement:{value:keyWord}} = this
      		//发送请求前通知List更新状态
      		PubSub.publish('atguigu',{isFirst:false,isLoading:true})
      		//发送网络请求
      		axios.get(`/api1/search/users?q=${keyWord}`).then(
      			response => {
      				//请求成功后通知List更新状态
      				PubSub.publish('atguigu',{isLoading:false,users:response.data.items})
      			},
      			error => {
      				//请求失败后通知App更新状态
      				PubSub.publish('atguigu',{isLoading:false,err:error.message})
      			}
      		)
      	}
      	render() {
      		return (
      			<section className="jumbotron">
      				<h3 className="jumbotron-heading">搜索github用户</h3>
      				<div>
      					<input ref={c => this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/>&nbsp;
      					<button onClick={this.search}>搜索</button>
      				</div>
      			</section>
      		)
      	}
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      import React, { Component } from 'react'
      import PubSub from 'pubsub-js'
      import './index.css'
      
      export default class List extends Component {
        //初始化状态
        state = { 
        	users:[], //users初始值为数组
        	isFirst:true, //是否为第一次打开页面
        	isLoading:false,//标识是否处于加载中
        	err:'',//存储请求相关的错误信息
        } 
        // 初始化
        componentDidMount(){
            // 订阅消息
        	this.token = PubSub.subscribe('atguigu',(_,stateObj)=>{
        		this.setState(stateObj)
        	})
        }
        // 卸载前
        componentWillUnmount(){
            // 取消订阅
        	PubSub.unsubscribe(this.token)
        }
        render() {
            // 获取
        	const {users,isFirst,isLoading,err} = this.state
        	return (
        		<div className="row">
        			{
        				isFirst ? <h2>欢迎使用,输入关键字,随后点击搜索</h2> :
        				isLoading ? <h2>Loading......</h2> :
        				err ? <h2 style={{color:'red'}}>{err}</h2> :
        				users.map((userObj)=>{
        					return (
        						<div key={userObj.id} className="card">
        							<a rel="noreferrer" href={userObj.html_url} target="_blank">
        								<img alt="head_portrait" src={userObj.avatar_url} style={{width:'100px'}}/>
        							</a>
        							<p className="card-text">{userObj.login}</p>
        						</div>
        					)
        				})
        			}
        		</div>
        	)
        }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      // Make sure to add code blocks to your code group

      # 扩展:Fetch

      fetch发送请求(关注分离的设计思想)

      # 特点

      1. fetch: 原生函数,不再使用XmlHttpRequest对象提交ajax请求

      2. 老版本浏览器可能不支持

      # get

      fetch(url).then(function(response) {
          return response.json()
        }).then(function(data) {
          console.log(data)
        }).catch(function(e) {
          console.log(e)
        });
      
      1
      2
      3
      4
      5
      6
      7

      # post

      fetch(url, {
      	method: "POST",
          body: JSON.stringify(data),
      }).then(function(data) {
          console.log(data)
      }).catch(function(e) {
          console.log(e)
      })
      
      1
      2
      3
      4
      5
      6
      7
      8

      # 案例(纯发送请求部分)

      基于以上案例修改

        fetch(`/api1/search/users2?q=${keyWord}`).then(
            response => {
                console.log('联系服务器成功了');
                return response.json()
            },
            error => {
                console.log('联系服务器失败了',error);
                return new Promise(()=>{})
            }
        ).then(
            response => {console.log('获取数据成功了',response);},
            error => {console.log('获取数据失败了',error);}
        ) 
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        try {
          const response= await fetch(`/api1/search/users2?q=${keyWord}`)
          const data = await response.json()
          PubSub.publish('atguigu',{isLoading:false,users:data.items})
        } catch (error) {
          console.log('请求出错',error);
          PubSub.publish('atguigu',{isLoading:false,err:error.message})
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        axios.get(`/api1/search/users2?q=${keyWord}`).then(
            response => {
                //请求成功后通知List更新状态
                PubSub.publish('atguigu',{isLoading:false,users:response.data.items})
            },
            error => {
                //请求失败后通知App更新状态
                PubSub.publish('atguigu',{isLoading:false,err:error.message})
            }
        ) 
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        // Make sure to add code blocks to your code group
        #React
        上次更新: 2024/08/14, 04:14:33
        React 应用
        React Router5

        ← React 应用 React Router5→

        最近更新
        01
        React Native 使用SVG
        08-13
        02
        Docker基础命令
        08-04
        03
        算数逻辑单元
        07-30
        更多文章>
        Theme by Vdoing | Copyright © 2021-2024 WeiXiaojing | 友情链接
        • 跟随系统
        • 浅色模式
        • 深色模式
        • 阅读模式