关于hooks:React学习笔记之Hooks

1. useStatestate 只在组件首次渲染的时候被创立 useState Hook: 容许咱们在函数组件中存储外部 state。 const [fruit, setFruit] = useState('banana'); //构造语法2. useEffectuseEffect Hook 可看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。  React 组件中有两种常见副作用操作:须要革除的和不须要革除的。咱们来更认真地看一下他们之间的区别。 when?euseEffect容许在组件加载和更新时执行操作。从概念上说,咱们心愿有些操作在每次渲染之后执行 —— 但 React 的 class 组件没有提供这样的办法。即便咱们提取出一个办法,咱们还是要在两个中央调用它。如把副作用操作放到 componentDidMount  和 componentDidUpdate 函数中 // 在class组件中componentDidMount() { //首次渲染时 document.title = `You clicked ${this.sta执行te.count} times`; } componentDidUpdate() { //更新时 document.title = `You clicked ${this.state.count} times`; }// 用useEffectuseEffect(()=>{ document.title = `You clicked ${count} times`; )Do what?Effect能够在React 组件渲染后执行某些操作。当 React 渲染组件时,React 会保留你传递的函数(咱们将它称之为 “effect”),并在更新完 DOM 后执行它。也就是说它在渲染之后和每次更新之后都会执行。React 保障了每次运行 effect 的同时,DOM 都曾经更新结束。咱们能够在 effect 中获取到最新的 变量值,变量值须要在函数的作用域内。这个过程在每次渲染时都会产生,包含首次渲染。 ps:传递给 useEffect 的函数在每次渲染中都会有所不同,这是刻意为之的。事实上这正是咱们能够在 effect 中获取最新的 count 的值,而不必放心其过期的起因。每次咱们从新渲染,都会生成新的 effect,替换掉之前的。某种意义上讲,effect 更像是渲染后果的一部分 —— 每个 effect “属于”一次特定的渲染。 ...

September 15, 2021 · 2 min · jiezi

关于hooks:当设计模式遇上-Hooks

简介: 数据结构与设计模式可能领导咱们在开发简单零碎中寻得一条清晰的路线,既然都说 Hooks 难以保护,那就尝试让「神」来援救这凌乱的场面。对于「设计模式是否有助于咱们写出更优雅的 Hooks 」这个问题,看完本文,置信你心中也会有本人的答案。 作者 | 阿晨起源 | 阿里技术公众号 一 前言「设计模式」是一个陈词滥调的话题,但更多是集中在面向对象语言畛域,如 C++,Java 等。前端畛域对于设计模式的探讨热度并不是很高,很多人感觉对于 JavaScript 这种典型的面向过程的语言来说,设计模式的价值很难体现。之前我持有相似的观点,对于设计模式的了解仅停留在概念层面,没有深刻去理解其在前端工程中的实际。近期浏览了《 JavaScript 设计模式与开发实际》一书,书中介绍了 15 种常见设计模式和根本的设计准则,以及如何应用 JavaScript 优雅实现并利用于理论工程中。碰巧前不久团队举办了一场对于 Hooks 的辩论赛,而 Hooks 的核心思想在于函数式编程,于是决定探索一下「设计模式是否有助于咱们写出更优雅的 Hooks 」这一话题。 二 为什么是设计模式在逆袭武侠剧中,主人公向第一位师父求教武艺时,最开始老师父只会让主人公挑水、扎马步等基本功,主人公这时总是会诸般埋怨,但又因为某些客观原因又不得不保持,之后开始学习真正的武艺时才顿悟之前老师父的一番苦心,夯实根底后学习武艺突飞猛进,最终成为一代大侠。对于咱们开发者来说,「数据结构」和「设计模式」就是老师父所教的基本功,它不肯定可能让咱们走得更快,但肯定能够让咱们走得更稳、更远,有助于咱们写出高牢靠且易于保护的代码,防止日后被 “挖坟”。 在 Hooks 公布以来,饱受诟病的一点就是保护老本激增,特地是对于成员能力程度差距较大的团队来说。即使一开始由经验老到的同学搭建整个我的项目框架,一旦交由新人保护一段时间后,大概率也会变得面目全非,更不用说让新人应用 Hooks 开发从零到一的工程。我了解这是因为 Hooks 的高度灵活性所导致的,Class Component 尚有一系列生命周期办法来束缚,而 Hooks 除了 API 参数上的束缚,也仅有 “只在最顶层应用 Hook” “只在 React 函数中调用 Hook” 两条强制规定。另一方面自定义 Hook 进步组件逻辑复用率的同时,也导致经验不足的开发者在形象时短少设计。Class Component 中对于逻辑的形象通常会形象为纯函数,而 Hooks 的封装则可能携带各种副作用(useEffect),呈现 bug 时排查老本较大。 那么既然「设计模式」是一种基本功,而「Hooks」是一种新招式,那咱们就尝试从设计模式登程,攻克新招式。 三 有哪些经典的设计模式在正式进入话题之前,咱们先简略回顾一下那些快被咱们忘记的经典设计模式和设计准则。日常中,咱们提到设计准则都会将其简化为「SOLID」,对应于繁多职责准则(Single Responsibility Principle)、凋谢/关闭准则(Open Closed Principle)、里氏代替准则(Liskov Substitution Principle)、最小晓得准则(Law of Demeter)、接口隔离准则(Interface Segregation Principle)和依赖倒置准则(Dependence Inversion Principle)。设计模式又包含了单例模式、策略模式、代理模式、迭代器模式、公布-订阅模式、命令模式、组合模式、模版办法模式、亨元模式、职责链模式、中介者模式、装璜者模式、状态模式、适配器模式等。 ...

September 1, 2021 · 2 min · jiezi

关于hooks:React-With-Reudx-Hooks详解

Hooks全面详解 意识Hooks1.Hook介绍Hook是 React 16.8 的新增个性,它能够让咱们在不编写class的状况下应用state以及其余的React个性 (比方生命周期) 2.class与function组件比照咱们先来思考一下class组件绝对于函数式组件有什么劣势?比拟常见的是上面的劣势:比照class组件function组件stateclass组件能够定义本人的state, 用来保留组件本人外部的状态函数式组件不能够,因为函数每次调用都会产生新的长期变量生命周期class组件有本人的生命周期, 咱们能够在对应的生命周期中实现本人的逻辑 ( 比方在componentDidMount中发送网络申请,并且该生命周期函数只会执行一次 )函数式组件在学习hooks之前,如果在函数中发送网络申请,意味着每次从新渲染都会从新发送一次网络申请render渲染class组件能够在状态扭转时只会从新执行render函数以及咱们心愿从新调用的生命周期函数componentDidUpdate等函数式组件在从新渲染时,整个函数都会被执行,仿佛没有什么中央能够只让它们调用一次所以,在Hook呈现之前,对于下面这些状况咱们通常都会编写class组件。3.Class组件存在的问题简单组件变得难以了解: 咱们在最后编写一个class组件时,往往逻辑比较简单,并不会非常复杂, 然而随着业务的增多,咱们的class组件会变得越来越简单比方componentDidMount中,可能就会蕴含大量的逻辑代码:包含网络申请、一些事件的监听(还须要在 componentWillUnmount中移除)而对于这样的class实际上十分难以拆分:因为它们的逻辑往往混在一起,强行拆分反而会造成适度设计,减少代码的复杂度难以了解的class: 很多人发现学习ES6的class是学习React的一个阻碍。比方在class中,咱们必须搞清楚this的指向到底是谁,所以须要花很多的精力去学习this尽管前端开发人员必须把握this,然而仍然解决起来十分麻烦组件复用状态很难: 在后面为了一些状态的复用咱们须要通过高阶组件或render props像咱们之前学习的redux中connect或者react-router中的withRouter,这些高阶组件设计的目标就是为了状态的复用或者相似于Provider、Consumer来共享一些状态,然而屡次应用Consumer时,咱们的代码就会存在很多嵌套这些代码让咱们不论是编写和设计上来说,都变得十分艰难4.Hook的呈现Hook的呈现,能够解决下面提到的这些问题简略总结Hooks 它能够让咱们在不编写class的状况下应用state以及其余的React个性然而咱们能够由此延长出十分多的用法,来让咱们后面所提到的问题失去解决Hook的应用场景: Hook的呈现根本能够代替咱们之前所有应用class组件的中央 (除了一些十分不罕用的场景)然而如果是一个旧的我的项目,你并不需要间接将所有的代码重构为Hooks,因为它齐全向下兼容,你能够渐进式的来应用它Hook只能在函数组件中应用,不能在类组件,或者函数组件之外的中央应用Hooks的体验计数器案例比照通过一个计数器案例,来比照一下class组件和函数式组件联合hooks的比照 State Hook意识useStateuseState来自react, 须要从react中导入, 它是一个Hook 参数: 初始化值, 如果不设置为undefined返回值: 数组, 蕴含两个元素 元素一: 以后状态的值(第一调用为初始化值)元素二: 设置状态值的函数import React, { useState } from 'react'const [counter, setCounter] = useState(0)Hook 补充Hook 就是 JavaScript 函数, 这个函数能够帮忙你钩入(hook into) React State以及生命周期等个性应用Hook的两个额定规定: 只能在函数最外层调用Hook。不要在循环、条件判断或者子函数中调用只能在 React 的函数组件中调用Hook。不要在其余 JavaScript 函数中调用useState 解析useState useState会帮忙咱们定义一个 state变量,useState是一种新办法,它与 class 外面的 this.state 提供的性能完全相同。一般来说,在函数执行结束后变量就会"隐没",而 state 中的变量会被 React 保留。useState接管一个惟一参数, 在第一次组件被调用时应用来作为初始化值useState是一个数组, 能够通过[数组的解构赋值](https://developer.mozilla.org...)来应用FAQ:为什么叫 useState 而不叫 createState? ...

May 27, 2021 · 6 min · jiezi

关于hooks:useRef使用细节

应用useRef有段时间了,最近梳理了useRef的应用细节。 一、动机函数组件拜访DOM元素;函数组件拜访之前渲染变量。函数组件每次渲染都会被执行,函数外部的局部变量个别会从新创立,利用useRef能够拜访上次渲染的变量,相似类组件的实例变量成果。 1.2 函数组件应用createRef不行吗?createRef次要解决class组件拜访DOM元素问题,并且最佳实际是在组件周期内只创立一次(个别在构造函数里调用)。如果在函数组件内应用createRef会造成每次render都会调用createRef: function WithCreateRef() { const [minus, setMinus] = useState(0); // 每次render都会从新创立`ref` const ref = React.createRef(null); const handleClick = () => { setMinus(minus + 1); }; // 这里每次都是`null` console.log(`ref.current=${ref.current}`) useEffect(() => { console.log(`denp[minus]>`, ref.current && ref.current.innerText); }, [minus]); return ( <div className="App"> <h1 ref={ref}>Num: {minus}</h1> <button onClick={handleClick}>Add</button> </div> );}二、应用2.1 根本语法见文档 每次渲染useRef返回值都不变;ref.current发生变化并不会造成re-render;ref.current发生变化应该作为Side Effect(因为它会影响下次渲染),所以不应该在render阶段更新current属性。2.2 不能够在render里更新ref.current值在Is there something like instance variables提到: Unless you’re doing lazy initialization, avoid setting refs during rendering — this can lead to surprising behavior. Instead, typically you want to modify refs in event handlers and effects.在render里更新refs导致什么问题呢?在异步渲染里render阶段可能会屡次执行。 ...

September 22, 2020 · 2 min · jiezi

关于hooks:hooks-中使用dva

hooks 中应用dvareacts hooks曾经问世很久了明天来记录下如何在hooks是应用dva,家喻户晓函数是不能够是不能够应用修饰符润饰的,因为函数存在变量晋升问题。所以大多数人有抉择再次掏出本人的redux,然而redux应用起来的确没有dva不便,那么上面就让咱们看看如何在hooks中优雅的应用dva吧! 废话不多说间接上代码! index.jsimport React from 'react';import { connect } from 'dva';import {Button} from 'antd';const mapStateToProps = (state)=> { return { home: state.home, }};const usePage = (props) => {const {home} = props; const btnClick = () => { const {dispatch} = props; dispatch({ type:"home/getList", payload: !home.likes }) }; return ( <div> <Button onClick={btnClick}>点击有惊喜</Button> <span>{home.likes ? 'true' : 'false'}</span> </div> );};export default connect(mapStateToProps, null)(usePage);model.jsexport default { namespace: 'home', state: { likes: null, }, effects: {}, reducers: { getList(state, {payload}) { return {...state, likes: payload}; }, },};为了简略我连css以及副作用都不要了。够简略不? 不会还不会吧? ...

August 1, 2020 · 1 min · jiezi

React-Hooks-你真的用对了吗

从 React Hooks 正式发布到现在,我一直在项目使用它。但是,在使用 Hooks 的过程中,我也进入了一些误区,导致写出来的代码隐藏 bug 并且难以维护。这篇文章中,我会具体分析这些问题,并总结一些好的实践,以供大家参考。 问题一:我该使用单个 state 变量还是多个 state 变量?useState 的出现,让我们可以使用多个 state 变量来保存 state,比如: const [width, setWidth] = useState(100);const [height, setHeight] = useState(100);const [left, setLeft] = useState(0);const [top, setTop] = useState(0);但同时,我们也可以像 Class 组件中的 this.state 一样,将所有的 state 放到一个 object 中,这样只需一个 state 变量即可: const [state, setState] = useState({ width: 100, height: 100, left: 0, top: 0});那么问题来了,到底用单个 state 变量还是多个 state 变量呢? 如果使用单个 state 变量,每次更新 state 时需要合并之前的 state。它不像 Class 组件的 this.setState 方法,会把更新的字段合并到 state 对象中。useState 返回的 setState 会替换原来的值: ...

October 8, 2019 · 7 min · jiezi

结合React的Effect-Hook分析组件副作用的清除

一个订阅好友在线的组件我们在DidMount的时候通过ID订阅了好友的在线状态并且为了防止内存泄漏,我们需要在WillUnmount清除订阅 但是当组件已经显示在屏幕上时,friend prop 发生变化时会发生什么? 我们的组件将继续展示原来的好友状态。这是一个 bug。而且我们还会因为取消订阅时使用错误的好友 ID 导致内存泄露或崩溃的问题。 class FriendStatus extends React.Component { constructor(props) { super(props); this.state = { isOnline: null }; this.handleStatusChange = this.handleStatusChange.bind(this); } componentDidMount() { ChatAPI.subscribeToFriendStatus( this.props.friend.id, this.handleStatusChange ); } componentWillUnmount() { ChatAPI.unsubscribeFromFriendStatus( this.props.friend.id, this.handleStatusChange ); } handleStatusChange(status) { this.setState({ isOnline: status.isOnline }); } render() { if (this.state.isOnline === null) { return 'Loading...'; } return this.state.isOnline ? 'Online' : 'Offline'; }}优化订阅好友在线的组件为了解决props更新导致的BUG我们需要在DidUpdate中进行修改订阅 componentDidMount() { ChatAPI.subscribeToFriendStatus( this.props.friend.id, this.handleStatusChange ); } componentDidUpdate(prevProps) { // 取消订阅之前的 friend.id ChatAPI.unsubscribeFromFriendStatus( prevProps.friend.id, this.handleStatusChange ); // 订阅新的 friend.id ChatAPI.subscribeToFriendStatus( this.props.friend.id, this.handleStatusChange ); } componentWillUnmount() { ChatAPI.unsubscribeFromFriendStatus( this.props.friend.id, this.handleStatusChange ); }引入Hooks代码会变得十分简单Effect HookuseEffect() 可以让你在函数组件中执行副作用操作默认情况下,它在第一次渲染之后和每次更新之后都会执行。 ...

October 8, 2019 · 2 min · jiezi

使用-Taro-Hooks-快速开发一个小程序-GitHub-Pro

在 Taro Hooks 出来 之后就一直想着体验一波 Hooks 小程序开发,不过一直忙着补番 ????。最近补完了,就搞了起来,开发了 20 天左右(其实大部分时间都在改 UI????),基本上是完成了,然后也上架了,遂跟大家分享一点心得 ???? 可以先扫描体验: 网络不稳定的小伙伴看预览: 在 GitHub Pro 的开发中,我写了四个 hooks,来帮助我提高开发效率 useRequestuseRequestWithMoreuseReachBottomEventusePullDownRefreshEvent接下来就分析一下它们的作用 useRequest作用同名字,用来进行网络请求,传入请求参数以及进行请求的函数,存储数据,返回 [currData, refresh] ,其中currData是存储的返回数据,refresh用于刷新请求。 function useRequest<T>( params: any, request: (params: any) => Promise<T | null>): [T | null, () => void] | [] { const [currData, setData] = useState<T | null>(null) const [count, setCount] = useState(0) const pagePullDownRef = useRef('') useEffect(() => { request(params).then(data => { if (data) { setData(data) } }) }, [count]) usePullDownRefresh(() => { refresh() }) useEffect(() => { events.on(PULL_DOWN_REFRESH_EVENT, (page: string) => { if (!pagePullDownRef.current) { pagePullDownRef.current = page } else if (pagePullDownRef.current !== page) { return } refresh() }) return () => { events.off(PULL_DOWN_REFRESH_EVENT) } }, []) const refresh = () => { setCount(count + 1) } return [currData, refresh]}export default useRequestuseRequest ...

September 19, 2019 · 3 min · jiezi

看完这篇你也能把-React-Hooks-玩出花

本文首发于政采云前端团队博客:看完这篇,你也能把 React Hooks 玩出花本文中出现的部分名称映射: 函数式组件 => Function Component 类组件 => Class Component 工具函数 => Util Function 钩子 => React Hook 初始值 => initialValue 先讲概念React v16.7.0-alpha 中第一次引入了 Hooks 的概念,在 v16.8.0 版本被正式发布。React Hooks 在 React 中只是对 React Hook 的概念性的描述,在开发中我们用到的实际功能都应该叫做 React hook。 React Hook 是一种特殊的函数,其本质可以是函数式组件(返回 Dom 或 Dom 及 State ),也可以只是一个工具函数(传入配置项返回封装后的数据处理逻辑)。 再总结React Hooks 的出现使函数式组件变得焕然一新,其带来的最大的变化在于给予了函数式组件类似于类组件生命周期的概念,扩大了函数式组件的应用范围。 目前函数式组件基本用于纯展示组件,一旦函数式组件耦合有业务逻辑,就需要通过 Props 的传递,通过子组件触发父组件方法的方式来实现业务逻辑的传递,Hooks 的出现使得函数组件也有了自己的状态与业务逻辑,简单逻辑在自己内部处理即可,不再需要通过 Props 的传递,使简单逻辑组件抽离更加方便,也使使用者无需关心组件内部的逻辑,只关心 Hooks 组件返回的结果即可。 在我看来,Hooks 组件的目标并不是取代类组件,而是增加函数式组件的使用率,明确通用工具函数与业务工具函数的边界,鼓励开发者将业务通用的逻辑封装成 React Hooks 而不是工具函数。 ...

September 9, 2019 · 4 min · jiezi

使用React-hooks处理复杂表单状态数据

使用hooks替换this.setState() 自从React hooks*发布以来已经有一段时间了,我很喜欢这个特性。这个hooks把我勾上了! Hooks允许我们创建更小,可组合,可重用,更易管理的React组件。 您可能正在使用Hooks的一个用例是:使用useState或useReducer管理表单状态。 让我们考虑一个场景,您必须管理具有多个输入的复杂表单状态,这些表单输入可以是几种不同的类型,如文本,数字,日期输入。表单状态甚至可以具有嵌套信息,例如用户的地址信息,它具有子字段,例如address.addressLine1,address.addressLine2等。 也许您还必须根据当前状态更新表单状态,例如toggle切换按钮。 现在,如果您对每个单独的表单字段使用useState,那么您可以根据当前状态计算新状态。 但是,如果你有太多单独的表单字段,比如100+,那么这种方法并不友好。 脑补一下... 编写单独的useStates,然后为每个字段使用单独的更新函数是不切实际的。我们的另一个选择是hook,useReducer。 我们来看一个例子。 呃,不好。您不可能为reducer中的n个表单字段编写每个用例。 但是,useReducer中使用的reducer函数只是一个返回更新状态对象的普通函数。所以,我们可以做得更好。 这样看起来,reducer简洁干净多了。 但是,现在reducer更新参数中如果有回调函数,则不能基于当前状态计算新状态,因为当前state没有传递给回调函数作为参数。就像我们在useState一样: useState中的更新函数可以基于prev参数计算新状态 另外,如何更新嵌套状态如address.addressLine1,address.pinCode。 我们通过使用不那么理想的方法进行了很多关于管理复杂表单状态的讨论。让我告诉你解决方案。 因此,这是处理复杂表单场景的完整源代码。 我将稍微解释一下reducer(enhancedReducer)函数。 reducer函数接收两个参数,第一个参数是更新前的当前状态。当您调用updateState / dispatch函数来更新reducer状态时,将自动提供此参数。 reducer函数的第二个参数是用于更新state。它不一定是采用{type:'something',payload:'something'}形式的典型redux动作对象。它甚至可以是任何东西,数字,字符串,对象或函数。 这就是我们的做法。如果updateArg是一个函数,我们用当前状态调用它来计算新函数。无论我们从这个函数返回什么对象都成为我们的新状态。 如果updateArg是一个普通的旧Javascript对象,那么有两种情况。 1:该对象没有_path和_value属性,因此是一个普通的更新对象,就可以像使用this.setState一样。因此,您可以使用包含要更新的状态片段的新对象调用updateState,并将其与旧状态合并并返回新状态。 2:对象具有_path和_value属性- 当使用具有这两个属性的对象作为参数,调用更新回调函数时。我们将此视为一种特殊情况,其中_path表示嵌套的字段路径。在字符串形式中,例如:'address.pinCode'或表示路径['address','pinCode']的数组。 我们如何使用此类路径表示来更新对象中的嵌套字段?我们将使用lodash的set方法。它接受路径表单作为更新和对象的有效输入。 但是,set方法就地改变对象并且不返回新副本,但在React世界中,更改检测取决于Immutability(不可变)。需要一个全新的数据副本,在内存中有一个新位置来触发渲染。 为了绕过这个,我们使用immer,来轻松地处理Javascript对象的不变性。 immer中的produce函数将对象作为其第一个参数进行处理,在我们的例子中是当前状态,它的第二个参数是一个函数,它接收对象的草稿副本以进行mutate,无论你在这个函数内修改了什么草稿状态,是在副本上完成的,而不是实际的输入对象状态。 然后,它会自动返回包含更新数据的新对象。 这就是我们的增强版reducer。 安装一下依赖,就可以跑起来了。 PS:在enhancedReducer中可以处理更多边缘情况,动态字段映射也可以缩短一些代码,减少代码重复和其他一些事情。 参考资源: Lodash文档: https://lodash.com/docs/4.17.... immerjs/immer: https://github.com/immerjs/im... 还可以关注头条号:「前端知否」

September 9, 2019 · 1 min · jiezi

仿Excel-React-hook-文章待续

Excel Editor 实现 (Virtual Table 部分)该小项目已经初步完成,写该文章是来练习写文章的。 目前文章进度较慢。 技术栈react (hooks)typescript项目及微软ExcelOnline喜欢就给上star吧 小项目演示地址 小项目Github地址 Microsoft Excel online 背景面试需要做一个小项目,下面是该项目的题目: 使用 TypeScript 开发一个简易版的 Excel WebApp,实现 column & row sort,cell edit,cell calculate 等,可以定义该 MVP 功能集。可以不借助框架或者使用主流框架问题Typescript 以前有了解,但是是第一次使用,简单的使用应该不成问题。Excel 是要实现到何种程度?功能实现,排序,编辑好说,计算这一个是要实现与Excel相同的函数功能么?框架还是要用的,毕竟时间有限这里准备直接使用create react app来开始项目思考从上面总结的问题只有两个地方比较不确认。 描述中提到了Excel, Excel只是表格,如果只是做成简单的表格恐怕不能得到太多的关注,这里决定做出与Excel一样的VirtualTable功能基于上面的virtualtable,实现排序编辑和计算的功能。基本的方向定了后便是整个实现步骤 基本的virtualtable实现选区功能的实现基于选区功能的其它功能实现(设计成插件方式,各个功能独立分隔)

September 7, 2019 · 1 min · jiezi