【React】知识点归纳:组件间通信、事件监听理解及ES6 常用新语法

本文深入探讨了React中组件间通信的三种主要方式:通过props传递、使用消息订阅-发布机制以及Redux。同时,文章也讲解了事件监听的理解,并介绍了ES6的一些常用新语法,如箭头函数、解构赋值等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、组件间通信

方式一: 通过 props 传递
  1. 共同的数据放在父组件上, 特有的数据放在自己组件内部(state)
  2. 通过 props 可以传递一般数据和函数数据, 只能一层一层传递
  3. 一般数据–>父组件传递数据给子组件–>子组件读取数据
  4. 函数数据–>子组件传递数据给父组件–>子组件调用函数
方式二: 使用消息订阅(subscribe)-发布(publish)机制
  1. 工具库: PubSubJS
  2. 下载: npm install pubsub-js --save
  3. 使用:
    import PubSub from ‘pubsub-js’ //引入
    PubSub.subscribe(‘delete’, function(data){ }); //订阅
    PubSub.publish(‘delete’, data) //发布消息

通过案例来理解使用消息订阅(subscribe)-发布(publish)机制

组件与组件之间的通信案例

注:该案例由于跨域问题还未解决,发送ajax请求时报错,正在解决中。
app.jsx

import React,{Component} from 'react'
import Search from './search'
import Main from './main'

export default class App extends Component{

    render (){
        return(
            <div className="container">
            <Search  />
            <Main />
            </div>
        )
    }
}

main.jsx

import React,{Component} from 'react'
import PropTypes from 'prop-types'
import axios from 'axios'
import PubSub from 'pubsub-js'


export default class Main extends Component{
/*
    // 当父组件传属性到子组件中时 先声明属性
    static propTypes = {
        searchName:PropTypes.string.isRequired
    }*/
    //main 有四个状态 初始化状态
    state = {
        initView:true,
        loading:false,
        users:null,
        errorMsg:null,

    }

    componentDidMount (){
        //订阅消息(search)
            PubSub.subscribe('search', (msg,searchName) =>{//指定了新的searchName,需要发出请求
                console.log(searchName)
                //更新状态 (请求中)
                this.setState ({
                    initView:false,
                    loading:true,
                })
                //发ajax请求
                // const url = 'http://api.githup.com/search/users?q=${searchName}'
                const url = "http://api.githup.com/search/users?q="+searchName
                // const url = 'http://localhost:53801/api/Project/Query?ProjectName='+searchName

                axios.get(url)
                    .then(response =>{
                        // 得到响应数据
                        const result = response.data
                        console.log(result)
                        console.log(1)
                        // const users = sult.items.map(item => ({name:item.}))  //item 返回一个对象 所以用小括号
                        const users = result.items.map(item => {
                            return {name:item.login,url:item.html_url,avatarUrl:item.avatar_url}
                        })
                        // 更新状态(成功)
                        this.setStata({
                            loading:false,
                            users
                        })
                    })
                    .catch(error=>{
                        //更新状态(失败)
                        console.log(2)
                        this.setState({
                            loading:false,
                            errorMsg:error.message
                        })
                    })
            })
    }
    
    render (){
        const {initView,loading,users,errorMsg}= this.state
        const {searchName} = this.props
        console.log('render ()',searchName)
        if (initView){
            return <h2>请输入关键进行搜索:{searchName}</h2>
        }else if(loading){
            return <h2>正在请求中...</h2>
        }else if(errorMsg){
            return <h2>{errorMsg}</h2>
        }else {
            return(
                <div className="row">
                    {
                        users.map((user,index) =>(
                            <div className="card" key={index}>
                                <a href={user.url} >
                                    <img src={user.avatarUrl} style={{width: 100}}/>
                                </a>
                                <p className="card-text">user.name</p>
                            </div>
                        ))
                    }
                </div>
            )
        }
    }
}

search.jsx

import React,{Component} from 'react'
import PropTypes from 'prop-types'
import PubSub from 'pubsub-js'

export default class Search extends Component{

    search = () => {
        //得到输入的关键字
        const searchName = this.input.value.trim()
        if(searchName){
            //在搜索
            //发布消息(search)
            PubSub.publish('search',searchName)
        }
    }

    render (){
        return(
            <section className="jumbotron">
                <h3 className="jumbotron-heading">Search Github Users</h3>
                <div>
                    <input type="text" placeholder="enter the name you search"  ref={ input => this.input = input}/>
                    <button onClick={this.search}>Search</button>
                </div>
            </section>
        )
    }
}
组件与孙子组件之间的通信案例

删除list下的评论,app.jsx要跨越一个comment-list.jsx组件与comment-item.jsx组件传递消息

app.jsx

import React,{Component} from 'react'
import PropTypes from 'prop-types'
import PubSub from 'pubsub-js'
import './commentItem.css'

export default class CommentItem extends Component{

    static  propTypes = {
        comment:PropTypes.object.isRequired,
        index:PropTypes.number.isRequired,
    }

    handleClick = () =>{
        const {comment,index} = this.props
        // console.log(deleteComment)
        console.log(index)
        //提示删除
        if(window.confirm("确定删除"+comment.username+"的评论吗?")){
            //确定后删除
           
           		//发布消息
            PubSub.publish('deleteComment',index)
       
        }
    }

    render (){
        const {comment}= this.props
        return(
            <li className="list-group-item">
                <div className="handle">
                    <a href="javascript:;" onClick={this.handleClick}>删除</a>
                </div>
                <p className="user"><span >{comment.username}</span><span >说:</span></p>
                <p className="centence">{comment.content}</p>
            </li>

        )
    }
}

comment-item.jsx(孙子组件)

import React,{Component} from 'react'
import PropTypes from 'prop-types'
import PubSub from 'pubsub-js'
import './commentItem.css'

export default class CommentItem extends Component{

    static  propTypes = {
        comment:PropTypes.object.isRequired,
        index:PropTypes.number.isRequired,
    }

    handleClick = () =>{
        const {comment,index} = this.props
        // console.log(deleteComment)
        console.log(index)
        //提示删除
        if(window.confirm("确定删除"+comment.username+"的评论吗?")){
            //确定后删除
            //发布消息
            PubSub.publish('deleteComment',index)
        }
    }

    render (){
        const {comment}= this.props
        return(
            <li className="list-group-item">
                <div className="handle">
                    <a href="javascript:;" onClick={this.handleClick}>删除</a>
                </div>
                <p className="user"><span >{comment.username}</span><span >说:</span></p>
                <p className="centence">{comment.content}</p>
            </li>

        )
    }
}
方式三: redux

(详细讲解网址:)

二、事件监听理解

原生 DOM 事件
  1. 绑定事件监听
    a. 事件名(类型): 只有有限的几个, 不能随便写
    b. 回调函数
  2. 触发事件
    a. 用户操作界面
    b. 事件名(类型)
    c. 数据()
自定义事件(消息机制)
  1. 绑定事件监听
    a. 事件名(类型): 任意
    b. 回调函数: 通过形参接收数据, 在函数体处理事件
  2. 触发事件(编码)
    a. 事件名(类型): 与绑定的事件监听的事件名一致
    b. 数据: 会自动传递给回调函数

三、ES6 常用新语法

  1. 定义常量/变量: const/let

  2. 解构赋值: let {a, b} = this.propsimport {aa} from 'xxx'

  3. 对象的简洁表达: {a, b}

  4. 箭头函数:
    a. 常用场景

    • 组件的自定义方法: xxx = () => {}
    • 参数匿名函数

    b. 优点:

    • 简洁
    • 没有自己的 this,使用引用 this 查找的是外部 this
  5. 扩展(三点)运算符: 拆解对象(const MyProps = {}, <Xxx {…MyProps}>)

  6. 类: class/extends/constructor/super

  7. ES6 模块化: export default | import

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值