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 事件处理]

猜你喜欢

转载自blog.csdn.net/A_bad_horse/article/details/105565246