React 函数讲解

学习目标

  • 纯函数
  • React函数三种写法
  • React事件处理

纯函数

  • 首先得是一个函数。

  • 当给定相同的输入(函数的参数)的时候,总是有相同的输出(返回值)。

  • 没有副作用。

  • 不依赖于函数外部状态。

当一个函数满足以上条件时,该函数可以称为是纯函数。

// 非纯函数let payload = 0;
function addOne(number) {
    ++payload;
    return number + payload;
}
addOne(1); // 2
addOne(1); // 3
addOne(1); // 4

// 纯函数
function addOne(number) {
    return number + 1;
}
addOne(1); // 2
addOne(1); // 2
addOne(1); // 2

上面两个栗子中,第一个就是典型的非纯函数,当第一次执行 addOne(1) 其返回的值是 2 没有错,但是再次执行相同函数的时候,其返回的值不再是 2 了,而是变成了 3 ,对比上面列出的满足纯函数的条件,就会发现:

  • addOne() 给定相同的输入的时候没有返回相同的输出;

  • addOne() 会产生副作用(会改变外部状态 payload);

  • addOne() 依赖的外部状态 payload 。

而第二个栗子就是一个纯函数,它既不依赖外部状态也不会产生副作用,且当给定相同输入的时候,总是返回相同的输出(执行任意多次 addOne(1) 总是返回 2 )。

React 官方定义

A JavaScript library for building user interfaces.
专注于构建 View 层的一个库
 
UI 只是把数据通过映射关系变成另一种形式的数据。给定相同的输入(数据)必然会有相同的输出(UI),即一个简单的纯函数。 ---( Sebastian Markbåge [React 的核心开发者之一])
 
 
数据:父组件通过props传递给子组件,渲染相同的UI界面。
view: 包含数据的渲染结果。

实例一 非纯函数

import React, { Children } from 'react';
import ReactDOM from 'react-dom';
class ShowTime extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      time: new Date().toLocaleTimeString()
    }
  }
  render () {
    return (
      <div>
        <h1>现在时间是:{this.state.time}</h1>
      </div>
    )
  }
}
ReactDOM.render(
  <ShowTime />, // 渲染父元素
  document.querySelector('#root') //寻找文件对象
)

从运行结果可知:该组件依赖于函数Date()。相同输入,对应的输出是不一样的(时间不一样)。
所以组件不是一个「纯函数」。实际开发中组件之间还存在数据交互,因此非纯函数也是常见的。
 

React函数三种写法

  • 写法一:通过bind实现函数内部this指向该实例,bind的第一个参数是context,即this。
import React, { Children } from 'react';
import ReactDOM from 'react-dom';
import { render } from '@testing-library/react';
class Test extends React.Component {
    constructor(props) {
        super(props);
        this.setName = this.setName.bind(this);
    }
}
/**
* @param name
*/
setName(name) {
  ...
};
render() {
    return (
        <div>
            <button onClick={this.setName}>点击获取姓名</button>
        </div>
    )
}
onClick={this.setName},函数类似是一个参数传递。重点是事件bind。
 
  • 写法二:箭头式函数(声明时采用箭头函数的形式)
import React, { Children } from 'react';
import ReactDOM from 'react-dom';
import { render } from '@testing-library/react';
class Test extends React.Component {
    constructor(props) {
        super(props);
        ...
    }
}
/**
* @param name
*/
setName = (name) => {
  ...
};
render() {
    return (
        <div>
            <button onClick={this.setName}>点击获取姓名</button>
        </div>
    )
}

构造器中无需绑定事件。箭头会从自己的作用域链上层继承this,这个this就会指向这个类的实例。

  • 写法三:箭头式函数(调用时采用箭头函数传参)
import React, { Children } from 'react';
import ReactDOM from 'react-dom';
import { render } from '@testing-library/react';
class Test extends React.Component {
    constructor(props) {
        super(props);
        ...
    }
}
/**
* @param name
*/
setName(name) {
  ...
};
render() {
    return (
        <div>
            <button onClick={(name) => this.setName(name)}>点击获取姓名</button>
        </div>
    )
}

类似于写法二,在调用处使用箭头函数。

React 事件处理

React中的事件处理一般与函数相结合。
 
HTML 通常写法是:
<button onclick="activateLasers()">
  激活按钮
</button>

React 中写法为:

<button onClick={activateLasers}>
  激活按钮
</button>

React 写法特点

  • React 事件绑定属性的命名采用驼峰式写法,而不是小写。
  • 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM 元素的写法)
向事件处理程序传参
 

删除id对应的那一行。

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
 
上述两种方式是等价的。参数 e 作为 React 事件对象将会被作为第二个参数进行传递。通过箭头函数的方式,事件对象必须显式的进行传递,但是通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。
 

参考链接:

https://segmentfault.com/a/1190000017750929 [React 中的函数式思想]

https://www.cnblogs.com/xiaochengzi/p/9674709.html [React内三种函数的写法]
 
https://www.runoob.com/react/react-event-handle.html [React 事件处理]
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React Refs 是 React 提供的一种访问 DOM 元素或组件实例的方法。通过 Refs,我们可以在组件中直接访问到被 Refs 引用的 DOM 元素或组件实例,从而进行一些特殊的操作。 下面,我来举一个 React Refs 的案例: 假设我们有一个 Input 组件,需要在组件加载完毕后自动获取焦点,我们可以通过 Refs 来实现这个功能。具体的实现步骤如下: 1. 在 Input 组件中定义 Refs: ```jsx class Input extends React.Component { constructor(props) { super(props); this.inputRef = React.createRef(); // 创建 Refs } render() { return <input type="text" ref={this.inputRef} />; } } ``` 2. 在 componentDidMount 生命周期中,使用 Refs 获取到 input 元素,并调用 focus() 方法: ```jsx class Input extends React.Component { constructor(props) { super(props); this.inputRef = React.createRef(); // 创建 Refs } componentDidMount() { this.inputRef.current.focus(); // 获取 input 元素并获取焦点 } render() { return <input type="text" ref={this.inputRef} />; } } ``` 这样,当 Input 组件加载完毕后,它的 input 元素就会自动获取焦点了。 注意,Refs 只能在类组件中使用,不能在函数式组件中使用。另外,Refs 的值可以是回调函数,而不仅仅是 React.createRef() 方法返回的对象。如果使用回调函数的方式,可以在回调函数中访问到组件实例或 DOM 元素,例如: ```jsx class Input extends React.Component { constructor(props) { super(props); this.inputRef = null; // 创建 Refs this.setInputRef = element => { this.inputRef = element; }; } componentDidMount() { this.inputRef.focus(); // 获取 input 元素并获取焦点 } render() { return <input type="text" ref={this.setInputRef} />; } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值