从函数式编程理解 React Hooks

本文介绍了React Hooks在函数式编程中的应用,详细阐述了useState、useReducer、useContext(自变量)以及useMemo、useCallback、useEffect(因变量)的使用方法和示例。还探讨了useRef的追踪特性,以及如何通过自定义Hook实现逻辑复用。最后,文章提供了相关学习资源。
摘要由CSDN通过智能技术生成

2019 年 2 月 6 日,React 官方 推出 React v16.8.0,稳定的 Hooks 功能出世。

React Hooks 和 函数式组件的配合,更能适应函数式编程的思维。

  1. 数学上定义的函数公式是:y = f(x)
  2. 如果将状态 state视为 输入 x视图 UI视为 输出 y,编写的函数组件为 Fn,那么可以写出这样一个式子:UI = Fn(state)

  1. 将 React 的 Hooks,按自变量和因变量划分

自变量

为什么说这三个 hook 是自变量呢?

因为他们如果值发生改变,会导致组件UI更新,和依赖它们这些值的 Hook 发生变化。

按照我们上述的 UI = Fn(state),他们就相当于这些 state

useState

基本使用

// 创建 state 的方式
const [state, setState] = useState(defaultState)

// 更新方式一:传值
setState(nextState);

// 更新方式二:传函数
// 传入的函数,会接收到一个参数是原先 state 的值,该函数的返回值将作为更新后 state 的值
setState(preState => nextState);

示例

// 写一个组件:input 框的值改变,p 标签的值跟着改变
import { useState } from 'react';

function StateDemo(props) {
  const [val, setVal] = useState('');
  const changeHandler = (e) => setVal(e.target.value)

  return (
    <div>
      <input onChange={changeHandler} />
      <p>{val}</p>
    </div>
  )
}

export default StateDemo

useReducer

基本使用

// 创建方式
/**
  * 传入参数:
  *  reducer{Function}: 形如 (state, action) => {},该函数返回的值作为更新的 reducerState
  *  initialArg{any}: 若无 init 初始化函数,则 initialArg 直接作为 reducerState。
  *                   若有 init 初始化函数,则 initialArg 作为 init 参数
  *  init{Function}: init 函数的返回值,作为初始化的 reducerState
  * 输出参数
  *  reducerState{any}: 状态
  *  dispatch{Function}: 用来更新状态
  */
const [reducerState, dispatch] = useReducer(reducer, initialArg, init);

示例

import { useReducer } from 'react';

const reducer = (state, action) => {
  const { count } = state;
  switch (action.type) {
    case 'increment':
      return { count: count + 1 }
    case 'decrement':
      return { count: count - 1 }
    default:
      return { count: count }
  }
}

const init = (initialArg) => {
  return { count: initialArg }
}

function ReducerDemo(props) {
  const [reducerState, dispatch] = useReducer(reducer, 0, init);

  return (
    <div>
      <p>{reducerState.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>递增</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>递减</button>
    </div>
  )

}

export default ReducerDemo

useContext

在 useContext 推出之前,我们使用 createContext 的方式如下

// Father 组件
import { Component, createContext } from 'react';
export const Context = createContext();

class Father extends Component {
	state = {
  	name: 'John'
  }
  render() {
  	return (
      <Context.Provider value={this.state.name}>
        <Son />
      </Context.Provider>
    )
  }
}
// Son 组件
import { Component } from 'react';
import { Context } from './Father'
// 类组件的写法如下
class Son extends Component {

  render() {
		return (
      <Context.Consumer>
        {
          (value) => <p>{value}</p>
        }
      </Context.Consumer>
    )
  }
}

// 函数式组件的写法如下
function Son(props) {
  return (
    <Context.Consumer>
      {
        (value) => <p>{value}</p>
      }
    </Context.Consumer>
  )
}
export default Son;

在 useContext 推出之后,我们使用 createContext 的方法有了变化

基本使用

useContext需要和 createContext配合使用

// 创建一个 context 实例
const ContextInstance = createContext(defaultValue);

// 使用 useContext 获取到 context 实例的值
const contextValue = useContext
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值