react组件之间的通信

时间:2021-10-30 06:34:42

通过props传递

共同的数据放在父组件上, 特有的数据放在自己组件内部(state),通过props可以传递一般数据和函数数据, 只能一层一层传递

一般数据-->父组件传递数据给子组件-->子组件读取数据

函数数据-->子组件传递数据给父组件-->子组件调用函数(相当于vue当中的自定义事件)

案例在:react中使用Ajax请求(axios,Fetch)在这篇文章的分别使用axios和fetch实现一个搜索案例中就有

使用消息订阅(subscribe)-发布(publish)机制

PubSubJS可以用在任何关系的组件中,如果传递的参数有多个就封装成对象

工具库: PubSubJS。下载: npm install pubsub-js --save

在需要的组件中引入:import PubSub from 'pubsub-js'

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

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

还是拿react中使用Ajax请求(axios,Fetch)在这篇文章的分别使用axios和fetch实现一个搜索的案例来修改

父组件中什么都不用做,只负责引入两个子组件search-list和search-input

import React, {Component} from 'react'
import './search.css';

import SearchInput from './search-input/search-input'
import SearchList from './search-list/search-list'
class Search extends Component {
  render() {
    return (
      <div className='search-axios'>
        <div className='search-input-cantain'>
          <SearchInput/>
        </div>
        <div className='search-list-cantain'>
          <SearchList />
        </div>
      </div>
    )
  }
}
export default Search

消息发布写在发送数据的组件中,比如这个案例中发送数据的是search-input这个组件

import React, {Component} from 'react'
import './search-input.css';
import PubSub from 'pubsub-js'

class SearchInput extends Component {
  handleSearch = () => {
    // 获取输入框中的数据
    const searchName = this.searchName.value

    // 使用PubSub发布消息,第一个参数是消息名,第二个参数是这个消息的值
    if (searchName) {
      PubSub.publish('search', searchName)
    }

    // 清空输入框中的数据
    this.searchName.value = ''
  }

  render() {
    return (
      <div className='search-input'>
        <input type='text' ref={input => this.searchName = input} placeholder='enter the name you search'/>
        <button onClick={this.handleSearch}>Search</button>
      </div>
    )
  }
}
export default SearchInput

消息订阅写在接收消息的组件中(search-list),订阅消息写在组件的componentDidMount(初始化已经挂载)周期函数中

import React, {Component} from 'react'
import './search-list.css';
import PubSub from 'pubsub-js'
import axios from 'axios'

class SearchList extends Component {

  state = {
    initView: true,
    loading: false,
    users: [],
    errorMsg: null
  }

  // 在此方法中启动定时器/绑定监听/发送ajax请求
  async componentDidMount () {
    PubSub.subscribe('search', (msg, searchName) => {
      // 这个回调函数必须有两个参数,第一个是消息名,第二个是订阅的消息的值
      const url = `https://api.github.com/search/users?q=${searchName}`
      this.setState({ initView: false, loading: true })
      axios.get(url)
        .then((response) => {
          this.setState({ loading: false, users: response.data.items })
        })
        .catch((error) => {
          console.log('error', error.response.data.message, error.message)
          this.setState({ loading: false, errorMsg: error.message })
        })
    });
  }

  render() {
    const {initView, loading, users, errorMsg} = this.state

    if (initView) {
      return <div className='search-hide-enter'>enter the name you search</div>
    } else if (loading) {
      return <div className='search-ing'>搜索中,请稍后.....</div>
    } else if (errorMsg) {
      return <div className='search-error'>{errorMsg}</div>
    } else {
      return (
        <div className='search-list'>
          {users.map((user, index) => (
            <div className='search-item' key={index}>
              <div className='search-item-img'><img src={user.avatar_url} alt='user'/></div>
              <p className='search-item-name'>{user.login}</p>
            </div>
          ))}
        </div>
      )
    }
  }
}
export default SearchList

redux