React教程:4 个 useState Hook 示例
摘要: React示例教程。
- 原文:快速了解 React Hooks 原理
 - 译者:前端小智
 
到 React 16.8 目前为止,如果编写函数组件,然后遇到需要添加状态的情况,咱们就必须将组件转换为类组件。
编写 class Thing extends React.Component,将函数体复制到render()方法中,修复缩进,最后添加需要的状态。
今天,可以使用 Hook 获得相同的功能,并为自己节省了工作时间。在本文中,主要介绍useState hook。
useState 做啥子的
useState hook 允许咱们向函数组件添加状态,我们通常称这些为“ hooks”,但它们实际上是函数,与 React 16.8 捆绑在一起。 通过在函数组件中调用useState,就会创建一个单独的状态。
在类组件中,state 总是一个对象,可以在该对象上添加保存属性。
对于 hooks,state 不必是对象,它可以是你想要的任何类型-数组、数字、布尔值、字符串等等。每次调用useState都会创建一个state块,其中包含一个值。
示例1:使用 useState 显示/隐藏组件
这个示例是一个组件,它显示一些文本,并在末尾显示一个read more链接,当单击链接时,它展开剩下的文本。
    import React, { useState } from 'react';
    import ReactDOM from 'react-dom';
    // 两个 props:
    //   text - 显示的内容
    //   maxLength - 在点击“read more”之前显示多少个字符
    function LessText({ text, maxLength }) {
      // 创建一个状态,并将其初始化为“true”
      const [hidden, setHidden] = useState(true);
      if (text <= maxLength) {
        return <span>{text}</span>;
      }
      return (
        <span>
          {hidden ? `${text.substr(0, maxLength).trim()} ...` : text}
          {hidden ? (
            <a onClick={() => setHidden(false)}> read more</a>
          ) : (
            <a onClick={() => setHidden(true)}> read less</a>
          )}
        </span>
      );
    }
    ReactDOM.render(
      <LessText
        text={`专注、努力是成功的真正关键。把你的眼睛盯在目标上,然后朝着目标迈出下一步`}
        maxLength={35}
      />,
      document.querySelector('#root')
    );
仅用一行代码,我们就使这个函数组件有状态:
    const [hidden, setHidden] = useState(true);
但是这个函数到底在做什么呢?如果每次渲染都调用它(确实如此),它又是如何保留状态的。
Hooks 实现的技巧
这里的“神奇”之处是,React在每个组件的幕后维护一个对象,并且在这个持久对象中,有一个“状态单元”数组。当你调用useState时,React将该状态存储在下一个可用的单元格中,并递增数组索引。
假设你的 hooks 总是以相同的顺序调用(如果遵循 hooks 的规则,它们将是相同的顺序),React能够查找特定useState调用的前一个值。对useState的第一个调用存储在第一个数组元素中,第二个调用存储在第二个元素中,依此类推。
这也不是很神奇的事情,主要它依赖于你可能没有想过的事实:咱们写的的组件是由React调用 ,所以它可以在调用组件之前事先做好一些工作。 而且,渲染组件的行为不仅仅是函数调用。 像<Thing />这样的JSX被编译为React.createElement(Thing) - 显然 React 可以控制它的调用方式和时间。
示例2:根据之前的状态更新状态
看看另一个例子:根据前一个值更新state的值。
咱们要造个计步器,每点击一次按钮,就计一次,点击完后,它会告诉你你走了多少步。
    import React, { useState } from 'react';
    function StepTracker() {
      const [steps, setSteps] = useState(0);
      function increment() {
        setSteps(steps => steps + 1);
      }
      return (
        <div>
          总共走了 {steps} 步!
          <br />
          <button onClick={increment}>
            点点我,步数不是个事!
          </button>
        </div>
      );
    }
    ReactDOM.render(
      <StepTracker />,
      document.querySelector('#root')
    );
首先,通过调用useState创建一个新的state,并将其初始化为0。它返回steps的当前值0和setSteps函数来更新 steps,用 increment函数来对steps进行增 1 操作。
这里还可以优化的提取increment函数,可以直接将 increment 函数里面的内联到 onClick 里面:
    <button onClick={() => setSteps(steps => steps + 1)}>
      I took another step
    </button>
示例3: state 作为数组
记住,state可以保存任何你想要的值。下面是一个随机数列表的例子,单击按钮将向列表添加一个新的随机数:
    function RandomList() {
      const [items, setItems] = useState([]);
      const addItem = () => {
        setItems([
          ...items,
          {
            id: items.length,
            value: Math.random() * 100
          }
        ]);
      };
      return (
        <>
          <button onClick={addItem}>Add a number</button>
          <ul>
            {items.map(item => (
              <li key={item.id}>{item.value}</li>
            ))}
          </ul>
        </>
      );
    }
注意,我们state初始化为空数组[],并在addItem函数中更新值。
setItems 更新 state 不会将旧值“合并” - 它会使用新值覆盖state。 这与this.setState在类中的工作方式不同。
示例4:具有多个键的 state
再来看看,state为对象的例子,创建一个包含2个字段的登录表单:username 和password。
下面示例主要展示如何在一个state对象中存储多个值,以及如何更新单个值。
    function LoginForm() {
      const [form, setValues] = useState({
        username: '',
        password: ''
      });
      const printValues = e => {
        e.preventDefault();
        console.log(form.username, form.password);
      };
      const updateField = e => {
        setValues({
          ...form,
          [e.target.name]: e.target.value
        });
      };
      return (
        <form onSubmit={printValues}>
          <label>
            Username:
            <input
              value={form.username}
              name="username"
              onChange={updateField}
            />
          </label>
          <br />
          <label>
            Password:
            <input
              value={form.password}
              name="password"
              type="password"
              onChange={updateField}
            />
          </label>
          <br />
          <button>Submit</button>
        </form>
      );
    }
如果想试试,可查看 CodeSandbox。
首先,我们创建一个state片段,并用一个对象初始化它
    const [form, setValues] = useState({
      username: '',
      password: ''
    })
这看起来像是在类中初始化状态的方式。
还有一个处理提交的函数,其中,e.preventDefault来阻止页面刷新并打印出表单值。
updateField函数更有意思。它使用setValues传递一个对象,为了确保现有的状态不被覆盖,这里使用了展开运算(...form)。
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
原文:https://daveceddia.com/usestate-hook-examples/
关于Fundebug
Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了20亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家免费试用!
React教程:4 个 useState Hook 示例的更多相关文章
- React简单教程-4-事件和hook
		
前言 在上一章 React 简单教程-3-样式 中我们建立了一个子组件,并稍微美化了一下.在另一篇文章 React 简单教程-3.1-样式之使用 tailwindcss 章我们使用了 tailwind ...
 - [React] Write a stateful Component with the React useState Hook and TypeScript
		
Here we refactor a React TypeScript class component to a function component with a useState hook and ...
 - WPF入门教程系列二十三——DataGrid示例(三)
		
DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...
 - 2015某编程网易语言vip课堂全套教程 包含post,hook入门到精通等
		
2015某编程网易语言vip课堂全套教程 包含post,hook入门到精通等 官方论坛弄来的 如果在官方下载需要权限的 挺不错教程 想学习易语言入门到精通 post hook js改写的可以看 ...
 - XamarinAndroid组件教程RecylerView适配器设置动画示例
		
XamarinAndroid组件教程RecylerView适配器设置动画示例 [示例1-3]下面将在RecylerView的子元素进行滚动时,使用适配器动画.具体的操作步骤如下: (1)创建一个名为R ...
 - [转]React 教程
		
本文转自:http://www.runoob.com/react/react-install.html React 可以直接下载使用,下载包中也提供了很多学习的实例. 本教程使用了 React 的版本 ...
 - SAP官网发布的react教程
		
大家学习React的时候,用的是什么教程呢?Jerry当时用的阮一峰博客上的入门教程,因为React使用的JSX语法并不是所有的浏览器都支持,所以还得使用browser.js在浏览器端将JSX转换成J ...
 - 看完阮一峰的React教程后, 我写了一个TodoList
		
看完阮一峰的React教程后,就自己做了这个TodoList,自己慢慢琢磨效率差了点但是作为入门小练习还是不错的. 以下是效果图:我的源码:todolistUI:bootstrap 4 一.组件化 我 ...
 - react教程 — 性能优化
		
参考:https://segmentfault.com/a/1190000007811296?utm_medium=referral&utm_source=tuicool 或 https: ...
 
随机推荐
- GO基础之Map
			
go开发手册: https://studygolang.com/pkgdoc 一.什么是map 有资料翻译成地图.映射或字典.但是大多数习惯上翻译成集合.1.map是Go中的内置类型,它将一个值与 ...
 - 微信小程序新服务消息推送 —— 订阅消息
			
微信团队前不久公测了「订阅消息」,原有的小程序模板消息接口将于 2020 年 1 月 10 日下线,届时将无法发送模板消息.「订阅消息」将完全替代「模板消息」,这两天得空测试了一波. 1.下发权限机制 ...
 - form-data、x-www-form-urlencoded、raw、binary的区别(非原创)
			
文章大纲 一.form-data介绍二.x-www-form-urlencoded介绍三.raw介绍四.binary介绍五.参考文章 一.form-data介绍 http请求中的multipart/f ...
 - Linux:LAMP环境的搭建
			
LAMP环境的搭建 安装DNS服务器 安装DNS服务 yum install bind -y DNS的配置 创建正向解析 以创建一个名为"lsy.com"的正向查找区域为例: 第一 ...
 - Linux:DNS服务器搭建
			
DNS简介 DNS(Domain Name System)域名系统: 是一种采用客户端/服务器机制,负责实现计算机名称与IP地址转换的系统.DNS作为一种重要的网络服务,既是国际互联网工作的基础,同时 ...
 - Linux:用户权限管理
			
用户与用户组的概念 超级用户 拥有对系统的最高管理权限,默认是 root 用户 普通用户 只能对自己目录下的文件进行访问和修改,具有登录系统的权限. 虚拟用户 也叫"伪"用户,这类 ...
 - JVM-6-垃圾回收算法
			
三如何垃圾回收 GC(Garbage Collection)垃圾回收算法 标记清除 速度快,但是会产生内存碎片: 标记整理 解决了标记清除内存碎片的问题,但是每次都得移动对象,因此成本 ...
 - 201871010105-曹玉中《面向对象程序设计(Java)》第一周学习总结
			
201871010105-曹玉中<面向对象程序设计(Java)>第一周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这 ...
 - LeetCode解题笔记 - 3. Longest Substring Without Repeating Characters
			
Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...
 - BZOJ2339/LG3214 「HNOI2011」 卡农  组合数学
			
问题描述 BZOJ2339 本题的一些心得 对于这种无序集合计数类问题,可以通过对方案数除以某个数的阶乘,使得无序化变为有序化. 设计DP方程时候,应该先有序的列出状态转移方程每一项的来源,并一项项推 ...