react 学习笔记

本文是React学习笔记,详细介绍了React的基础知识,包括组件、事件处理、状态管理和props。讨论了事件对象、this上下文、call和apply、箭头函数以及组件的state和setState。同时,讲解了渲染列表数据、组件周期、ref属性、style和PropTypes等关键概念。文章旨在帮助读者深入掌握React开发。

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

 

目录

基础小知识

event 对象   

事件中的 this

call 和 apply

箭头函数

props

组件的 state 和 setState

关于 state 和 props 的总结

渲染列表数据

如何向同级组件传递信息呢?

组件周期

ref 属性

style

PropTypes 和组件参数验证

高阶组件


学习资源来自   React.js 小书

  • 基础小知识

  • 组件一般都需要继承 React.js 的 component。一个组件类必须要实现一个 render 方法,这个 render 方法必须要返回一个 JSX 元素。但这里要注意的是,必须要用一个外层的 JSX 元素把所有内容包裹起来。
  • 在 JSX 当中(1 标签内部 2 标签的属性)你可以插入 JavaScript 的表达式,用大括号 { } 包起来。里面可以放任何 JavaScript 的代码,包括变量、表达式计算、函数。
  • 实际上,JSX 元素其实就是JavaScript 对象。所以 JSX 元素可以像普通 js 对象一样自由的赋值给变量,或者作为参数传递、函数的返回值等。
  • 自定义组件必须要用大写字母开头,普通的 HTML 标签都用小写字母开头。
  • React.js 中的事件监听 :只需要给需要监听事件的元素加上属性类似于 onClick、onKeyDown的属性
    class Title extends Component {
      handleClickOnTitle () {
        console.log('Click on title.')
      }
    
      render () {
        return (
          <h1 onClick={this.handleClickOnTitle}>React 小书</h1>
        )
      }
    }

    onClick 紧跟着一个表达式插入,这个表达式返回一个 Title 自己的一个实例方法。

这些是 React 封装的不同的类型事件 SyntheticEvent - React 

note :没有经过特殊处理的话,这些 on* 的事件监听只能用在普通的 HTML 的标签上,而不能用在组件标签上。

  • event 对象   

和普通浏览器一样,事件监听函数会被自动的传入一个 event 对象。我们来尝试一下,当用户点击 h1 的时候,把 h1 的innerHTML 打印出来:

class Title extends Component {
  handleClickOnTitle (e) {
    console.log(e.target.innerHTML)
  }

  render () {
    return (
      <h1 onClick={this.handleClickOnTitle}>React 小书</h1>
    )
  }
}

这里的 e.target.innerHTML 是什么意思?

在触发DOM上的事件都会产生一个对象,即事件对象(也称event对象),这里用e接收事件对象。事件对象有很多属性和方法,此处的target属性是获取事件目标,即p元素DOM对象,然后获取其相应的属性

  • 事件中的 this

一般在某个类的实例方法里面的 this 指的是这个实例本身。但是你在上面的 handleClickOnTitle 中把 this 打印出来,你会看到 this 是 null 或者 undefined

...
  handleClickOnTitle (e) {
    console.log(this) // => null or undefined
  }
...

这是因为 React.js 调用你所传给他的方法的时候,并不是通过对象方法的方式调用(this.handleClickOnTitle),而是直接通过函数调用(handleClickOnTitle),所以事件监听函数内并不能通过 this 获取到实例。

如果想在事件函数当中使用当前的实例,你需要手动的将实例方法 bind 到当前实例上再传入给 React

class Title extends Component {
  handleClickOnTitle (e) {
    console.log(this)
  }

  render () {
    return (
      <h1 onClick={this.handleClickOnTitle.bind(this)}>React 小书</h1>
    )
  }
}

bind 方法如何使用?

ECMAScript 5 引入了Function.prototype.bind。调用 f.bind(someObject)会创建一个与 f 具有相同函数体和作用域的函数,但是在这个新函数中,this 将永久性(不能被再次绑定,也就是不能被再次赋值!)的被绑定到了 bind 的第一个参数,无论这个函数时如何被调用的。

  • call 和 apply

如果要想把 this 的值从一个上下文传到另一个,就要用到 call 或者 apply 方法。

// 将一个对象作为call和apply的第一个参数,this会被绑定到这个对象。
var obj = {a: 'Custom'};

// 这个属性是在global对象定义的。
var a = 'Global';

function whatsThis(arg) {
  return this.a;  // this的值取决于函数的调用方式
}

whatsThis();          // 'Global'
whatsThis.call(obj);  // 'Custom'
whatsThis.apply(obj); // 'Custom'

在函数中的应用

function add(c, d) {
  return this.a + this.b + c + d;
}

var o = {a: 1, b: 3};

// 第一个参数是作为‘this’使用的对象
// 后续参数作为参数传递给函数调用
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16

// 第一个参数也是作为‘this’使用的对象
// 第二个参数是一个数组,数组里的元素用作函数调用中的参数
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34
  • 箭头函数

  • props

每个组件都可以接受一个props参数,它是一个对象,包含了所有你对这个组件的配置。

如何把 props 穿进去呢?在使用一个组件的时候,可以把参数放在标签的属性当中,所有的属性都会作为 props 对象的键值

组件内部可以通过 this.props 来访问这些配置参数

已经讲过,JSX 的表达式插入可以在标签属性上使用。所以其实可以把任何类型的数据作为组件的参数,报空字符串、数字、对象、数组、甚至是函数。下面举一个函数的例子

class Index extends Component {
  render () {
    return (
      <div>
        <LikeButton
          wordings={{likedText: '已赞', unlikedText: '赞'}}
          onClick={() => console.log('Click on like button!')}/>
      </div>
    )
  }
}

note:当看到 {{ }} 不要慌张,其实就是在 { } 内部用对象字面量返回一个对象而已。

  • 组件的 state 和 setState

先来看一个例子

 

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './index.css'

class LikeButton extends Component {
  constructor () {
    super()
    this.state = { isLiked: false }
  }

  handleClickOnLikeButton () {
    this.setState({
      isLiked: !this.state.isLiked
    })
  }

  render () {
    return (
      <button onClick={this.handleClickOnLikeButton.bind(this)}>
        {this.state.isLiked ? '取消' : '点赞'} 
  • 关于 state 和 props 的总结

state 的主要作用是用于组件保存、控制、修改自己的可变状态。state 在组件内部初始化,可以被组件自身修改,而外部不能访问也不能修改。你可以认为 state 是一个局部的、只能被组件自身控制的数据源。state 中状态可以通过 this.setState方法进行更新,setState 会导致组件的重新渲染。

props 的主要作用是让使用该组件的父组件可以传入参数来配置该组件。它是外部传进来的配置参数,组件内部无法控制也无法修改。除非外部组件主动传入新的 props,否则组件的 props 永远保持不变。

state 和 props 有着千丝万缕的关系。它们都可以决定组件的行为和显示形态。一个组件的 state 中的数据可以通过 props 传给子组件,一个组件可以使用外部传入的 props 来初始化自己的 state。但是它们的职责其实非常明晰分明:state 是让组件控制自己的状态,props 是让外部对组件自己进行配置

 


  • 渲染列表数据

之前说过 JSX 的表达式插入 { } 里面可以放任何数据,如果我们往 { } 里面放一个存放 JSX 元素的数组会如何呢?

    React.js 会帮你把数组里面一个个元素罗列出来并且渲染出来。我们知道这一点之后,就能想到遇到数组,我们应该使用 map 方法。

    但是为了提高效率,现在需要记住一个简单的规则:对于用表达式套数组罗列到页面上的元素,都要为每个元素加上 key 属性,这个 key 必须是每个元素唯一的标识。


  • 如何向同级组件传递信息呢?

父组件只需要通过 props 给子组件传入一个回调函数。当用户点击按钮的时候,子组件调用 props 中的回调函数并且将 state 传入该函数。然后父组件向子组件中传递 props。

处理的原则就是:将这种组件之间的共享的状态交给组件最近的公共父节点保管,然后通过 props 把状态传递给子组件,这样就可以在组件之间共享数据了。React 将这种行为叫做 ‘状态提升’。

React 并没有提供好的解决方案来管理这种组件之间的共享状态。在实际项目当中状态提升并不是一个好的解决方案,所以我们后续会引入 Redux 这样的状态管理工具来帮助我们来管理这种共享状态。


  • 组件周期

我们把 React.js 将组件渲染,并且构造 DOM 元素然后塞入页面的过程称为组件的挂载。

React 为了让我们更好的掌控组件的挂载过程,往上面添加了三个方法:

  1. componentWillMount :组件挂载开始之前,也就是在组件调用 render 方法之前调用
  2. componentDidMount :组件挂载完成之后也就是 DOM 元素已经插入页面后调用。
  3. componentWIllUnmount :组件对应的 DOM 元素从页面中删除之前调用。
-> constructor()
-> componentWillMount()
-> render()
// 然后构造 DOM 元素插入页面
-> componentDidMount()
// ...
// 即将从页面中删除
-> componentWillUnmount()
// 从页面中删除

 


  • ref 属性

React 当中提供了 ref 属性来帮助我们获取已经挂载的元素的 DOM 节点,你可以给某个 JSX 元素加上 ref 属性。

class AutoFocusInput extends Component {
  componentDidMount () {
    this.input.focus()
  }

  render () {
    return (
      <input ref={(input) => this.input = input} />
    )
  }
}

ReactDOM.render(
  <AutoFocusInput />,
  document.getElementById('root')
)

我们给input 元素加了一个 ref 属性,属性值为一个函数。当 input 元素在页面上挂载完成以后,React 就会调用这个函数,并且把这个挂载以后的 DOM 节点传给这个函数。在函数中,我们把这个 DOM 元素设置为组件实例的一个属性,这样以后我们就可以通过 this.input 获取到这个 DOM 元素。


  • style

React.js 中的元素的 style 属性的用法和 DOM 里面的 style 不大一样,普通的 HTML 中的:

<h1 style='font-size: 12px; color: red;'>React.js 小书</h1>

在 React.js 中你需要把 CSS 属性变成一个对象再传给元素:

<h1 style={{fontSize: '12px', color: 'red'}}>React.js 小书</h1>

style 接受一个对象,这个对象里面是这个元素的 CSS 属性键值对,原来 CSS 属性中带 - 的元素都必须去掉 - 换成驼峰命名,如 font-size 换成 fontSize。


  • PropTypes 和组件参数验证

都说 JavaScript 是一门灵活的语言 —— 这就是像是说“你是个好人”一样,凡事都有背后没有说出来的话。

它的灵活性体现在弱类型上。在构建大型应用程序上其实更适合强类型的语言来构建,比如C/C++/JAVA。为了弥补 JavaScript 在这方面的缺陷,近年来出现了类似 TypeScript 和 Flow等技术。

React 的组件其实是为了构建大型应用程序而生。在你编写了一个组件以后,根本不知道别人会如何使用你的组件,往里面传什么乱七八糟的参数。

于是 React 就提供了这么一种机制,让你可以给组件的配置参数加上类型验证。他可以帮助我们验证 props 的参数类型。例如:

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

class Comment extends Component {
  static propTypes = {
    comment: PropTypes.object
  }

  render () {
    const { comment } = this.props
    return (
      <div className='comment'>
        <div className='comment-user'>
          <span>{comment.username} </span>:
        </div>
        <p>{comment.content}</p>
      </div>
    )
  }
}

React 提供的 propTypes 提供了一系列的数据类型可以用来配置组件的参数:

PropTypes.array
PropTypes.bool
PropTypes.func
PropTypes.number
PropTypes.object
PropTypes.string
PropTypes.node
PropTypes.element
...

更多类型及其用法可以参看官方文档: Typechecking With PropTypes - React

通过 PropTypes 给组件的参数做类型限制,可以在帮助我们迅速定位错误,这在构建大型应用程序的时候特别有用。

  • 组件的内容编写顺序如下:
  1. static 开头的类属性,如defaultProps、propTypes。
  2. 构造函数,constructor。
  3. getter / setter。
  4. 组件生命周期
  5.  _ 开头的私有方法。
  6. 事件监听方法 ,handle*。
  7. render* 开头的方法
  8. render( )方法。

组件的私有方法都用 _ 开头,所有事件监听的方法都用 handle 开头。把事件监听方法传给组件的时候,属性名用 on 开头。例如:

<CommentInput
  onSubmit={this.handleSubmitComment.bind(this)} />

这样统一规范处理事件命名会给我们带来语义化组件的好处,监听(onCommentInput 的 Submit 事件,并且交给 this 去处理(handle)。这种规范在多人协作的时候也会非常方便。

 



  • 高阶组件

高阶组件是一个函数,传给它一个组件,它返回一个新的组件。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值