博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
⑥ React 项目中的AJAX请求、组件间通信的2种方式(props、消息订阅和发布)
阅读量:3964 次
发布时间:2019-05-24

本文共 5728 字,大约阅读时间需要 19 分钟。

查看专栏其它文章:


React


本人是个新手,写下博客用于自我复习、自我总结。

如有错误之处,请各位大佬指出。
学习资料来源于:尚硅谷


AJAX请求 (使用axios)

在之前的文章中已经介绍过这部分用法,想要回顾可参照我的第 ④ 篇文章,如果对具体AJAX的用法不熟悉,可以参考文章:

因为推荐使用 axios,所以这里只用 axios 进行演示。在项目中使用的用法和之前相同。只不过需要注意,不要忘记在项目中先导入 axios:npm i axios --save

本次代码实现的功能如下图: ( 划分组件 )

在这里插入图片描述
根据划分组件,创建项目结构:(为方便已经简化,更具体的可参考我的第 ⑤ 篇文章)
在这里插入图片描述
app 依然为根组件。

index.js

import React from 'react'import ReactDOM from 'react-dom'import App from './components/app'import './index.css'ReactDOM.render(
, document.getElementById('root'))

app.jsx

import React from 'react'import Search from './search'import UserList from './user-list'export default class App extends React.Component {
state = {
searchName: '' } refreshName = (searchName) => this.setState({
searchName}) render() {
return (

Search Github Users

) }}

search.jsx

/** * 上部的搜索模块 */import React, {
Component} from 'react'import PropTypes from 'prop-types'class Search extends Component {
static propTypes = {
refreshName: PropTypes.func.isRequired } search = () => {
const name = this.nameInput.value.trim() if(name){
this.props.refreshName(name) } } render() {
return (
this.nameInput = input)}/>
) }}export default Search

user-list.jsx

/** * 下部的用户列表模块 */import React from 'react'import PropTypes from 'prop-types'import axios from 'axios'class UserList extends React.Component {
static propTypes = {
searchName: PropTypes.string.isRequired } state = {
firstView: true, loading: false, users: null, error: null } componentWillReceiveProps(nextProps) {
let searchName = nextProps.searchName console.log('发送ajax请求', searchName) const url = `https://api.github.com/search/users?q=${
searchName}` this.setState({
firstView: false, loading: true }) // 使用axios库 axios.get(url) .then((response) => {
console.log(response) this.setState({
loading: false, users: response.data.items }) }) .catch((error)=>{
// debugger console.log('error', error.response.data.message, error.message) this.setState({
loading: false, error: error.message }) }) } render () {
if (this.state.firstView) {
return

Enter name to search

} else if (this.state.loading) {
return

Loading result...

} else if (this.state.error) {
return

{
this.state.error}

} else {
return (
{
this.state.users.map((user) => (
user

{

user.login}

)) }
) } }}export default UserList

在这里使用到了之前在生命周期中提到过的,componentWillReceiveProps()。这个勾子函数的使用也是比较频繁的,它的作用是:组件将要接收到新的props时回调。而在上面代码的整个过程中,只要从输入框中输入新数据搜索信息时,就会将该搜索内容通过props的方式传递给该组件,因此将axios请求放在其中,就是十分合适的。


组件间通信


方式一: 通过props传递

对于第一种方式应该已经不陌生了,在这里就不放代码了。测试语法时,所有组件传递用的都是 props。那在项目中,我们通常将共同的数据放在父组件上,特有的数据放在各自组件内部 (state)。然后涉及到数据传递,用的就是 props。

从目前来看,它的特点是:可以传递一般数据和函数数据,且只能一层一层传递


方式二: 使用消息订阅(subscribe)-发布(publish)机制

对于这种方式,想要使用需要下载: npm install pubsub-js --save

它的使用方法:

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

它和 props 那种需要一层一层传递的区别是:消息订阅-发布的方式可以做到直接传递

接下来的演示代码将对上面AJAX部分的代码进行修改。

首先对于 app.jsx,之前的时候我们把共同的数据存放在父组件上,这样才能做到数据传递。但现在有了 消息订阅-发布的方式,我们已经不需要这么做了,现在可以做到直接传递:

import React from 'react'import Search from './search'import UserList from './user-list'export default class App extends React.Component {
render() {
return (

Search Github Users

) }}

然后对于搜索框组件 search.jsx,我们要将输入的数据传递给用户列表组件,去使用 axios 获取数据,此时我们只需 发布消息 即可。需要注意的是,消息名要和订阅消息时的消息名相同,比如在这里是 search。传递的消息是 searchName。

/** * 上部的搜索模块 */import React, {
Component} from 'react'import PubSub from 'pubsub-js'class Search extends Component {
search = () => {
const searchName= this.nameInput.value.trim() if(searchName){
//发布消息 PubSub.publish('search', searchName) } } render() {
return (
this.nameInput = input)}/>
) }}export default Search

因此,根据上述内容,订阅消息时其消息名一定要为 search才能匹配。这里的msg不用管,其实代表的是消息名。在这里接收传递过来消息的参数名是 searchName。但这个参数名,不一定要和发布消息时的相同。

/** * 下部的用户列表模块 */import React from 'react'import axios from 'axios'import PubSub from 'pubsub-js'class UserList extends React.Component {
state = {
firstView: true, loading: false, users: null, error: null } componentDidMount() {
//订阅消息 PubSub.subscribe('search',(msg,searchName) => {
const url = `https://api.github.com/search/users?q=${
searchName}` this.setState({
firstView: false, loading: true }) // 使用axios库 axios.get(url).then((response) => {
this.setState({
loading: false, users: response.data.items }) }).catch((error)=>{
this.setState({
loading: false, error: error.message }) }) }) } render () {
if (this.state.firstView) {
return

Enter name to search

} else if (this.state.loading) {
return

Loading result...

} else if (this.state.error) {
return

{
this.state.error}

} else {
return (
{
this.state.users.map((user) => (
user

{

user.login}

)) }
) } }}export default UserList

转载地址:http://rmyki.baihongyu.com/

你可能感兴趣的文章
VirtualBox上Ubuntu虚拟机反应慢
查看>>
Eclipse快捷键大全
查看>>
关于索引服务 X:/System Volume Information/catalog.wci/
查看>>
错误提示:The prefix "aop" for element "aop:config" is not bound.
查看>>
LazyInitializationException.java - could not initialize proxy - no Session
查看>>
sql常用语句速查手册
查看>>
eclipse安装插件SVN, GWT, implementors, Easy Explorer
查看>>
小组早晨例会
查看>>
SSH标准配置
查看>>
七个对我最好的职业建议(精简版)
查看>>
Struts 2 Auto Completer Example
查看>>
Installing the Microsoft Loopback Adapter for virtual pc.
查看>>
时间管理三招--转自刘润的博客
查看>>
迷茫的大学生(刘润,微软全球技术中心经理 )
查看>>
一份比较详细的DOS命令说明
查看>>
myeclipse 编辑jsp老死机
查看>>
MyEclipse不编译问题的解决
查看>>
Commons FileUpload组件使用方法(包含源代码)
查看>>
doubleselect用法 显示不换行
查看>>
应届毕业生培训计划
查看>>