React函数式组件Hooks开发

WHY

1.React 没有提供将可复用性行为“附加”到组件的途径(例如,把组件连接到 store)。
解决此类问题的方案:
一类:render props 和 高阶组件,需要重新组织你的组件结构。

如果你在 React DevTools 中观察过 React 应用,你会发现由 providers,consumers,高阶组件,render props 等其他抽象层组成的组件会形成“嵌套地狱”。
尽管我们可以在 DevTools 过滤掉它们,但这说明了一个更深层次的问题:React 需要为共享状态逻辑提供更好的原生途径。

可以使用 Hook 从组件中提取状态逻辑,使得这些逻辑可以单独测试并复用。Hook 使你在无需修改组件结构的情况下复用状态逻辑。 这使得在组件间或社区内共享 Hook 变得更便捷。

2.组件预编译会带来巨大的潜力
使用 class 组件会无意中鼓励开发者使用一些让优化措施无效的方案,而且class 也给目前的工具带来了一些问题。e.g:class 不能很好的压缩,并且会使热重载出现不稳定的情况。因此,推荐函数式

3.使用 Hook 其中一个目的就是要聚合功能模块,不被生命周期函数分割
比如useState实现值与setState的映射关系
比如effect解决 class 中生命周期函数经常包含不相关的逻辑,但又把相关逻辑分离到了几个不同方法中的问题。

函数式组件没有实例的概念,函数通过执行去渲染

//函数组件1.0
const Example = (props) => {
   
  // 你可以在这使用 Hook
  return <div />;
}

//函数组件2.0
function MyFunctionalComponent() {
   
 // 你可以在这使用 Hook
  return <input />;
}
  
class Parent extends React.Component {
   
  constructor(props) {
   
    super(props);
    this.textInput = React.createRef();
  }
  render() {
   
    // 这样没用!函数式组件根本就没有实例!
    return (
      <MyFunctionalComponent ref={
   this.textInput} />
    );
  }
}

Hook

React 16.8 的新增特性
在一些模块中包含了 React Hook 的稳定实现。
Hook 是能让你在函数组件中不编写 class 的情况下使用 state 以及其他的 React 特性。它们名字通常都以 use 开始

规定:
只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用。
只能在 React 的函数组件中调用 Hook。不要在其他 JavaScript 函数中调用。(还有一个地方可以调用 Hook —— 就是自定义的 Hook 中)

 useEffect(function persistForm() {
   
    // 👍 将条件判断放置在 effect 中
    if (name !== '') {
   
      localStorage.setItem('formData', name);
    }
  });

React Hooks 都是函数,在函数组件中使用,Hook 可以在函数组件里“钩入” React state 及生命周期等特性的函数。当React渲染函数组件时,组件里的每一行代码就会依次执行,Hooks 也就依次调用执行

useState

const [state, setState] = useState(initialState);

返回数组:state,以及更新 state 的函数。
在后续的重新渲染中,useState 返回的第一个值将始终是更新后最新的 state。React 会确保 setState 函数的标识是稳定的,并且不会在组件重新渲染时发生变化。
setState 函数用于更新 state,它接收一个新的 state 值并将组件的一次重新渲染加入队列。

如果 initialState 需要通过复杂计算获得,则可以传入一个函数,在函数中计算并返回初始的 state,此函数只在初始渲染时被调用

在这里插入图片描述

setState 同步or异步

React 中 setState 什么时候是同步的,什么时候是异步的?
React 控制之外的事件中调用 setState 是同步更新的。比如原生 js 绑定的事 件,setTimeout/setInterval 等。
由 React 控制的事件处理程序,以及生命周期函数调用 setState 不会同步更 新 state 。

在React的setState函数实现中,会根据一个变量isBatchingUpdates判断是直接更新this.state还是放到队列中回头再说,而isBatchingUpdates默认是false,也就表示setState会同步更新this.state,但是,有一个函数batchedUpdates,这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state。

useEffect

副作用:数据获取,设置订阅以及手动更改 React 组件中的 DOM 。

React 的 class 组件中,render 函数是不应该有任何副作用的,基本上都希望在 React 更新 DOM 之后才执行我们的操作。

副作用操作的分类:需要清除的和不需要清除的。

无需清除的操作:在 React 更新 DOM 之后运行一些额外的代码。比如发送网络请求,手动变更 DOM,记录日志

可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 三个函数的组合。通过使用这个 Hook, React 会保存你传递的函数(即effect),默认情况下,useEffect 在第一次渲染之后和每次更新之后都会执行(等同于同时使用componentDidMount 和componentDidUpdate ),另外也可以可以控制它。React 保证了每次运行 effect 的同时,DOM 都已经更新完毕。

与 componentDidMount 或 componentDidUpdate 不同,使用 useEffect 调度的 effect 不会阻塞浏览器更新屏幕,这让应用看起来响应更快。
大多数情况下,effect 不需要同步地执行。在个别情况下(例如测量布局),有单独的 useLayoutEffect Hook 供你使用,其 API 与 useEffect 相同。

useEffect 放在组件内部可以在 effect 中直接访问 count state 变量(或其他 props)。我们不需要特殊的 API 来读取它 —— 它已经保存在函数作用域中。

对比JavaScript的类中方法没有绑定this,Hook 使用了 JavaScript 的闭包机制,而不用在 JavaScript 已经提供了解决方案的情况下,还引入特定的 React API。

无需清除的effect

import React, {
    useState, useEffect } from 'react';

function Example() {
   
  const [count, setCount] = useState(0);

  useEffect(() => {
   
    document.title = `You clicked ${
     count<
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值