React 全栈体系(八)

news/2024/7/15 17:30:57 标签: react.js, 前端, 前端框架

第四章 React ajax

三、案例 – github 用户搜索

2. 代码实现

2.3 axios 发送请求
Search
/* src/components/Search/index.jsx */
import React, { Component } from "react";
import axios from 'axios'

export default class Search extends Component {

  search = () => {
    //获取用户的输入(连续解构赋值+重命名)
    const { keyWordElement:{value:keyword} } = this
    console.log(keyword);
    //发送网络请求
    axios.get(`https://api.github.com/search/users?q=${keyword}`).then(
      response => {console.log('c', response.data);},
      error => {console.log('d', error);}
    )
  }

  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>
    );
  }
}
2.4 展示数据
2.4.1 App
/* src/App.jsx */
import React, { Component } from "react";
import Search from "./components/Search";
import List from "./components/List";

export default class App extends Component {

  state = {users:[]} //初始化状态,users初始值为数组

  saveUsers = (users)=>{
    this.setState({users})
  }
  render() {
    const {users} = this.state
    return (
      <div className="container">
        <Search saveUsers={this.saveUsers}/>
        <List users={users}/>
      </div>
    );
  }
}
2.4.2 Search
/* src/components/Search/index.jsx */
import React, { Component } from "react";
import axios from 'axios'

export default class Search extends Component {

  search = () => {
    //获取用户的输入(连续解构赋值+重命名)
    const { keyWordElement:{value:keyword} } = this
    //发送网络请求
    axios.get(`https://api.github.com/search/users?q=${keyword}`).then(
      response => {
        this.props.saveUsers(response.data.items)
      },
      error => {console.log('d', error);}
    )
  }

  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>
    );
  }
}
2.4.3 List
/* src/components/List/index.jsx */
import React, { Component } from "react";
import "./index.css";

export default class List extends Component {
  render() {
    return (
      <div className="row">
        {this.props.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>
    );
  }
}
2.5 完成案例
2.5.1 App
/* src/App.jsx */
import React, { Component } from "react";
import Search from "./components/Search";
import List from "./components/List";

export default class App extends Component {
  state = {
    //初始化状态
    users: [], //users初始值为数组
    isFirst: true, //是否为第一次打开页面
    isLoading: false, //标识是否处于加载中
    err: "", //存储请求相关的错误信息
  };

  //更新App的state
  updateAppState = (stateObj) => {
    this.setState(stateObj);
  };

  render() {
    const { users } = this.state;
    return (
      <div className="container">
        <Search updateAppState={this.updateAppState} />
        <List {...this.state} />
      </div>
    );
  }
}
2.5.2 Search
/* src/components/Search/index.jsx */
import React, { Component } from "react";
import axios from "axios";

export default class Search extends Component {
  search = () => {
    //获取用户的输入(连续解构赋值+重命名)
    const {
      keyWordElement: { value: keyword },
    } = this;
    //发送请求前通知App更新状态
    this.props.updateAppState({ isFirst: false, isLoading: true });
    //发送网络请求
    axios.get(`https://api.github.com/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>
    );
  }
}
2.5.3 List
/* src/components/List/index.jsx */
import React, { Component } from "react";
import "./index.css";

export default class List extends Component {
  render() {
    const { users, isFirst, isLoading, err } = this.props;
    return (
      <div className="row">
        {isFirst ? (
          <h2>Welcome, enter a keyword and then click search!</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. 工具库

  • PubSubJS

2. 下载

  • npm install pubsub-js --save

3. 使用

  • import PubSub from ‘pubsub-js’ //引入
  • PubSub.subscribe(‘delete’, function(data){ }); //订阅
  • PubSub.publish(‘delete’, data) //发布消息

4. github 用户搜索代码重构

4.1 App
/* src/App.jsx */
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>
    );
  }
}
4.2 Search
/* src/components/Search/index.jsx */
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("alex", { isFirst: false, isLoading: true });
    //发送网络请求
    axios.get(`https://api.github.com/search/users?q=${keyword}`).then(
      (response) => {
        //请求成功后通知List更新状态
        PubSub.publish("alex", {
          isLoading: false,
          users: response.data.items,
        });
      },
      (error) => {
        //请求失败后通知List更新状态
        PubSub.publish("alex", { 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>
    );
  }
}
4.3 List
/* src/components/List/index.jsx */
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("alex", (_, stateObj) => {
      this.setState(stateObj);
    });
  }

  componentWillUnmount() {
    PubSub.unsubscribe(this.token);
  }

  render() {
    const { users, isFirst, isLoading, err } = this.state;
    return (
      <div className="row">
        {isFirst ? (
          <h2>Welcome, enter a keyword and then click search!</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>
    );
  }
}

五、扩展:Fetch

1. 文档

  • https://github.github.io/fetch/

2. 特点

  • fetch: 原生函数,不再使用 XmlHttpRequest 对象提交 ajax 请求
  • 老版本浏览器可能不支持

3. 相关 API

3.1 GET 请求
fetch(url).then(function(response) {
    return response.json()
  }).then(function(data) {
    console.log(data)
  }).catch(function(e) {
    console.log(e)
  });
3.2 POST 请求
fetch(url, {
  method: "POST",
  body: JSON.stringify(data),
}).then(function(data) {
  console.log(data)
}).catch(function(e) {
  console.log(e)
})

4. github 用户搜索代码 - fetch

Search
/* src/components/Search/index.jsx */
import React, { Component } from "react";
import PubSub from "pubsub-js";

export default class Search extends Component {
  search = async()=>{
		//获取用户的输入(连续解构赋值+重命名)
		const {keyWordElement:{value:keyWord}} = this
		//发送请求前通知List更新状态
		PubSub.publish('alex',{isFirst:false,isLoading:true})
		//#region 发送网络请求---使用axios发送
		/* axios.get(`https://api.github.com/search/users?q=${keyWord}`).then(
			response => {
				//请求成功后通知List更新状态
				PubSub.publish('alex',{isLoading:false,users:response.data.items})
			},
			error => {
				//请求失败后通知App更新状态
				PubSub.publish('alex',{isLoading:false,err:error.message})
			}
		) */
		//#endregion

		//发送网络请求---使用fetch发送(未优化)
		/* fetch(`https://api.github.com/search/users?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);}
		) */

		//发送网络请求---使用fetch发送(优化)
		try {
			const response= await fetch(`https://api.github.com/search/users?q=${keyWord}`)
			const data = await response.json()
			PubSub.publish('alex',{isLoading:false,users:data.items})
		} catch (error) {
			PubSub.publish('alex',{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>
    );
  }
}

六、总结

1.设计状态时要考虑全面,例如带有网络请求的组件,要考虑请求失败怎么办。
2.ES6小知识点:解构赋值+重命名
	let obj = {a:{b:1}}
	const {a} = obj; //传统解构赋值
	const {a:{b}} = obj; //连续解构赋值
	const {a:{b:value}} = obj; //连续解构赋值+重命名
3.消息订阅与发布机制
	1.先订阅,再发布(理解:有一种隔空对话的感觉)
	2.适用于任意组件间通信
	3.要在组件的componentWillUnmount中取消订阅
4.fetch发送请求(关注分离的设计思想)
	try {
		const response= await fetch(`/api1/search/users2?q=${keyWord}`)
		const data = await response.json()
		console.log(data);
	} catch (error) {
		console.log('请求出错',error);
	}

http://www.niftyadmin.cn/n/5044723.html

相关文章

DDR4 眼图测试方法

DDR的全拼是Double Data Rate SDRAM双倍数据速率同步动态随机存取内存。主要就是用在电脑的内存。他的特点就是走线数量多&#xff0c;速度快&#xff0c;操作复杂&#xff0c;给测试和分析带来了很大的挑战。目前DDR技术已经发展到了DDR5&#xff0c;性能更高&#xff0c;功耗…

Unity中Shader中UI材质去色功能实现

文章目录 前言一、实现思路1、在属性面板暴露一个 开关 来控制去色变体2、声明一个变体3、在片元着色器实现去色 二、实现1、定义开关2、声明变体3、在片元着色器中&#xff0c;使用宏判断是否去色法1、只输出结果的单通道值&#xff0c;一般来说结果不太理想&#xff0c;比较节…

Unicode和UTF-8区别

Unicode和UTF-8区别 Unicode是字符集&#xff0c; utf-8是编码规则

掷骰子的多线程应用程序2基于互斥量的线程同步(复现《Qt C++6.0》)

说明&#xff1a;在复现过程中出现两点问题&#xff08;1&#xff09;run()函数中对m_diceValued的赋值&#xff08;2&#xff09;do_timeOut()函数中没有对m_seq、m_diceValued进行定义。修改后的复现程序如下所示&#xff1a; 主线程&#xff1a; .h #pragma once#include…

建筑能源管理(1)——建筑能源管理的概念

1、什么是建筑能源管理 目前&#xff0c;主要有三种不同的类型能源管理&#xff1a; (1)节约型能源管理 又称“减少能耗型”能源管理。这种管理方式着眼于能耗数量上的减少&#xff0c;采取限制用能的措施。例如&#xff0c;在非人流高峰时段停开部分电梯、在室外气温特别高时…

动手吧,vue单选框

单选框到处可见&#xff0c;组件库不方便自定义样式&#xff0c;还是自己写吧。 效果图&#xff1a; 1、template部分 <template><labelclass"v-radio flex":class"[{ disable: disabled }]":aria-disabled"disabled"><spancla…

国庆中秋特辑(三)使用生成对抗网络(GAN)生成具有节日氛围的画作,深度学习框架 TensorFlow 和 Keras 来实现

要用人工智能技术来庆祝国庆中秋&#xff0c;我们可以使用生成对抗网络&#xff08;GAN&#xff09;生成具有节日氛围的画作。这里将使用深度学习框架 TensorFlow 和 Keras 来实现。 一、生成对抗网络&#xff08;GAN&#xff09; 生成对抗网络&#xff08;GANs&#xff0c;…

DPDK系列之三十内存中的环形队列

一、环形队列 环形队列是数据结构里一个常用的数据结构。一般来说&#xff0c;开发者对其基本都清楚&#xff0c;即使不清楚的翻翻书也就明白了。这里重点不再于讲环形队列的基本实现&#xff0c;那个资料太多了&#xff0c;这里也不再狗尾续貂。 环形队列在实际应用中最常用的…