2023-05-21
React
00

目录

React入门学习(二)面向组件编程
一、组件的使用
1. 函数式组件
二、组件实例三大属性
1. state
2. props
3. refs
4. 事件处理
5.包含表单元素的组件分为非受控租价与受控组件
高阶函数函数柯里化
不用高阶函数函数柯里化实现

React入门学习(二)面向组件编程

react

介绍React的入门讲解(二)

大家好,我是 小超 同学。最近我正在学习 React、阅读 JS 文档,并整理 Node 的笔记。对于 React,这是关于 React 的第二篇文章,也是我学习的第三个框架,内容如有错误,欢迎大家指正

祝愿你生活明朗,万物可爱!🌞🌻

一、组件的使用

当应用是以多组件的方式实现,这个应用就是一个组件化的应用

注意:

  1. 组件名必须是首字母大写
  2. 虚拟DOM元素只能有一个根元素
  3. 虚拟DOM元素必须有结束标签 < />

渲染类组件标签的基本流程

  1. React 内部会创建组件实例对象
  2. 调用render()得到虚拟 DOM ,并解析为真实 DOM
  3. 插入到指定的页面元素内部

1. 函数式组件

jsx
//1.先创建函数,函数可以有参数,也可以没有,但是必须要有返回值 返回一个虚拟DOM function Welcome (props) { return <h1>{props.name},我是用函数定义的组件(适用于【简单组件】 的定义)</h1> } // 2. 渲染處拟DOM到页面 ReactDOM.render(<Welcome name="hello"></Welcome>, document.getElementById("example"));

上面的代码经历了以下几步:

  1. React解析组件标签,找到了Welcome组件
  2. 我们调用 ReactDOM.render() 函数,并传入 <Welcome name="hello" /> 作为参数。
  3. React 调用 Welcome 组件,并将 {name: 'hello'} 作为 props 传入。
  4. Welcome 组件将 hello,我是用函数定义的组件(适用于【简单组件】 的定义) 元素作为返回值。
  5. 将返回的虚拟DOM转为真实DOM,随后呈现在页面中

2. 类式组件

jsx
// 1. 创建组件类 —— 本质就是创建一个类 class Welcome extends React.Component { //render是放在哪里的?类(Welcome)的原型对象上,供实例使用。 // render中的this是谁? render中的this是(Welcome)组件实例对象 render () { console.log('render中的this: ', this); return <h1>我是用类定义的组件(适用于【复尔组件】的定义) </h1> } } // 2. 渲染處拟DOM到页面 ReactDOM.render(<Welcome name="hello" />, document.getElementById("example"));

执行了ReactDoM.render(.……..….之后,发生了什么?

上面的代码经历了以下几步:

  1. React解析组件标签,找到了Welcome组件
  2. 发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法
  3. 将render返回的虚拟DOM转为真实DOM,随后呈现在页面中

在Class类式组件中遇到的问题

  1. 组件中的 render 方法中的 this 为组件实例对象
  2. 组件自定义方法中由于开启了严格模式,this 指向 undefined 如何解决
    1. 通过 bind 改变 this 指向
    2. 推荐采用箭头函数,箭头函数的 this 指向
  3. state 数据不能直接修改或者更新Ï

二、组件实例三大属性

1. state

React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。

React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。

简单的说就是组件的状态,也就是该组件所存储的数据

类式组件中的使用

https://image.myxuechao.com/blog/React/react-2.png

使用的时候通过this.state调用state里的值

在类式组件中定义state

  • 可以在构造器中初始化state
  • 也可以在类中添加属性state来初始化

修改 state

类式组件的函数中,直接修改state

jsx
const { isHot } = this.state isHot = !isHot

页面的渲染靠的是render函数

这时候会发现页面内容不会改变,原因是 React 中不建议 state不允许直接修改,而是通过类的原型对象上的方法 setState()

setState()

jsx
this.setState(partialState, [callback]);
  • partialState: 需要更新的状态的部分对象
  • callback: 更新完状态后的回调函数

正确写法:有两种写法:

  • 写法1
jsx
this.setState({ isHot:!isHot })
  • 写法2:
// 传入一个函数,返回x需要修改成的对象,参数为当前的 state this.setState(state => ({count: state.count+1});

setState是一种合并操作,不是替换操作

  • 在执行 setState操作后,React 会自动调用一次 render()
  • render() 的执行次数是 1+n (1 为初始化时的自动调用,n 为状态更新的次数)

2. props

state不同,state是组件自身的状态,而props则是外部传入的数据

类式组件中使用

https://image.myxuechao.com/blog/React/react-3.png

在使用的时候可以通过 this.props来获取值 类式组件的 props:

  1. 通过在组件标签上传递值,在组件中就可以获取到所传递的值
  2. 在构造器里的props参数里可以获取Ï到 props
  3. 可以设置  defaultProps 属性来操作 props的默认值,都是直接添加在类式组件的原型对象上的(所以需要添加 static
  4. 同时可以通过...运算符来简化

https://image.myxuechao.com/blog/React/react-4.png

函数式组件中的使用

函数在使用props的时候,是作为参数进行使用的(props)

https://image.myxuechao.com/blog/React/react-5.png

函数组件的 props定义:

  1. 在组件标签中传递 props的值
  2. 组件函数的参数为 props
  3. 对 props默认值同样设置在原型对象上

3. refs

Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素。

在我们正常的操作节点时,需要采用DOM API 来查找元素,但是这样违背了 React 的理念,因此有了refs

有三种操作refs的方法,分别为:

  • 字符串形式
  • 回调形式
  • createRef形式

字符串形式refs

https://image.myxuechao.com/blog/React/react-6.png

虽然这个方法废弃了,但是还能用,还很好用

回调形式的refs

组件实例的ref属性传递一个回调函数c => this.input1 = c (箭头函数简写),这样会在实例的属性中存储对DOM节点的引用,使用时可通过this.input1来使用

使用方法

jsx
<input ref={cur => this.input1 = cur } type="text" placeholder="点击按钮提示数据"/>

https://image.myxuechao.com/blog/React/react-7.png

我的理解

cur会接收到当前节点作为参数,ref的值为函数的返回值,也就是this.input1 = cur,因此是给实例下的input1赋值

createRef 形式(推荐写法)

React 给我们提供了一个相应的API,它会自动的将该 DOM 元素放入实例对象中

我们先给DOM元素添加ref属性

jsx
<input ref={this.MyRef} type="text" placeholder="点击弹出" /> <input ref={this.MyRef1} type="text" placeholder="点击弹出" />

通过API,创建React的容器,会将DOM元素赋值给实例对象的名称为容器的属性的current

jsx
MyRef = React.createRef(); MyRef1 = React.createRef();

注意:专人专用,一个节点创建一个容器

jsx
// 调用函数 showDate = () => { //创建之后,将自身节点,传入current中 alert(this.myRef.current.value) }

https://image.myxuechao.com/blog/React/react-8.png

注意:我们不要过度的使用 ref,如果发生时间的元素刚好是需要操作的元素,就可以使用事件对象去替代。过度使用有什么问题我也不清楚,可能有 bug 吧

4. 事件处理

  1. React 使用的是自定义事件,而不是原生的 DOM 事件
  2. React 的事件是通过事件委托方式处理的(为了更加的高效)
  3. 可以通过事件的 event.target获取发生的 DOM 元素对象,可以尽量减少 refs的使用

https://image.myxuechao.com/blog/React/react-9.png

这里都使用了ref 如果有很多就不合适了

5.包含表单元素的组件分为非受控租价与受控组件

  • 受控组件:表单组件的输入组件随着输入并将内容存储到状态中(随时更新)
  • 非受控组件:表单组件的输入组件的内容在有需求的时候才存储到状态中(即用即取)

实现一个小例子:一个表单用户输入框、一个密码输入框、一个登录的按钮然后输入完值后点击登录就可以拿到两个输入框的值

非受控组件

https://image.myxuechao.com/blog/React/react-10.png

这里使用的就是非受控组件,因为有两个输入框用户名密码 都是在最后点击登录调用handleSubmit 才用他们输入的数据所以就是非受控组件;使用的是ref绑定获取值最后点登录按钮调用函数获取它们两个输入框的值。

受控组件

https://image.myxuechao.com/blog/React/react-11.png

这里使用的是受控组件,因为有两个输入框,分别是用户名密码。它们在各自输入完后调用handleChange保存自己的状态到state,最后登录时调用handleChange,然后从state中获取两个输入框的数据,所以这就是受控组件。

高阶函数函数柯里化

上面的例子中最后点击登录调用handleChange 的函数柯里化写法 **handleChange**函数的第一个参数是一个字符串,而第二个参数是由React事件系统自动传递的事件对象,其中包含了事件触发时的相关信息

https://image.myxuechao.com/blog/React/react-12.png

在这段代码中,**onChange属性的值是一个箭头函数,它接收一个event参数,然后调用handleChange函数并传递了两个参数:一个表示需要更新的state属性名,一个是event事件对象。这样,handleChange函数就可以在内部使用event**对象来获取用户输入的文本,从而实现了双向数据绑定。

不用高阶函数函数柯里化实现

https://image.myxuechao.com/blog/React/react-13.png

对比上面的写法,这种写法的一个好处是可以直接在**onChange属性中处理事件,不需要在组件定义外部额外声明一个函数。另外,这种写法可以看作是显示地将event参数传递给handleChange**函数,让代码更加的清晰明了,同时也可以更容易地进行单元测试和调试。

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:LiuXueChao

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!