摘要: React示例教程。

到 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的当前值0setSteps函数来更新 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个字段的登录表单:usernamepassword

下面示例主要展示如何在一个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 示例的更多相关文章

  1. React简单教程-4-事件和hook

    前言 在上一章 React 简单教程-3-样式 中我们建立了一个子组件,并稍微美化了一下.在另一篇文章 React 简单教程-3.1-样式之使用 tailwindcss 章我们使用了 tailwind ...

  2. [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 ...

  3. WPF入门教程系列二十三——DataGrid示例(三)

    DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...

  4. 2015某编程网易语言vip课堂全套教程 包含post,hook入门到精通等

    2015某编程网易语言vip课堂全套教程 包含post,hook入门到精通等  官方论坛弄来的  如果在官方下载需要权限的  挺不错教程 想学习易语言入门到精通 post hook  js改写的可以看 ...

  5. XamarinAndroid组件教程RecylerView适配器设置动画示例

    XamarinAndroid组件教程RecylerView适配器设置动画示例 [示例1-3]下面将在RecylerView的子元素进行滚动时,使用适配器动画.具体的操作步骤如下: (1)创建一个名为R ...

  6. [转]React 教程

    本文转自:http://www.runoob.com/react/react-install.html React 可以直接下载使用,下载包中也提供了很多学习的实例. 本教程使用了 React 的版本 ...

  7. SAP官网发布的react教程

    大家学习React的时候,用的是什么教程呢?Jerry当时用的阮一峰博客上的入门教程,因为React使用的JSX语法并不是所有的浏览器都支持,所以还得使用browser.js在浏览器端将JSX转换成J ...

  8. 看完阮一峰的React教程后, 我写了一个TodoList

    看完阮一峰的React教程后,就自己做了这个TodoList,自己慢慢琢磨效率差了点但是作为入门小练习还是不错的. 以下是效果图:我的源码:todolistUI:bootstrap 4 一.组件化 我 ...

  9. react教程 — 性能优化

    参考:https://segmentfault.com/a/1190000007811296?utm_medium=referral&utm_source=tuicool  或  https: ...

随机推荐

  1. 怎么将CAD转PNG格式?这两种方法值得收藏

    在从事相关CAD工作的小伙伴们都知道,CAD中不光需要绘制各种各样的图纸,还需要根据工作的需要来进行图纸格式的转换工作.那有的时候就需要将CAD转换成PNG格式的图片进行使用.那怎么将CAD转PNG格 ...

  2. 网络协议 3 - 物理层 和 MAC 层

    在上一篇博文中,我们见证了 IP 地址的诞生,机器一旦有了 IP,就可以在网络的环境里和其他的机器展开沟通了.     今天,我们来认识下 物理层 和 MAC 层.     日常生活中,身为 90 后 ...

  3. vue $emit $on 从子组件传递数据给父组件

    原理是: 子组件使用$emit发送数据,父组件使用$on,或者v-on绑定, 来监听子组件发送的数据. 子组件: <button @click="sendChildData" ...

  4. 使用Anaconda3的Docker镜像

    假设本地 Ubuntu 服务器已经安装好了Docker,这里讲述一下如何开始运行Anaconda3的Docker镜像: 1. 搜索镜像 搜索我们想要的anaconda镜像: docker search ...

  5. sqlite数据类型与c#数据类型对应表

    SQLite 数据类型 C# 数据类型   BIGINT Int64   BIGUINT UInt64   BINARY Binary   BIT Boolean 首选 BLOB Binary 首选 ...

  6. [Linux] 常见的并发模型

    进程&线程(Apache) C10K问题异步非阻塞(Nginx,Libevent,NodeJS) 开发时复杂度高协程 (Golang Erlang lua) goroutine channel ...

  7. vue预览本地图片

    <template> <div> <a href="javascript:void(0);" @change="addImage" ...

  8. Matlab2019a启动慢,寻找许可证耽误时间解决办法

    Matlab2017b启动慢,一直处于初始化状态的解决办法 - 善水的博客 - CSDN博客 评论区给出了更为具体的做法,效果非常好. "D:\Program Files\MATLAB\R2 ...

  9. subprocess模块(了解)

    目录 一.subprocess模块 一.subprocess模块 subprocess模块允许你去创建一个新的进程让其执行另外的程序,并与它进行通信,获取标准的输入.标准输出.标准错误以及返回码等.更 ...

  10. vue中\$refs、\$emit、$on的使用场景

    1.$emit的使用场景 子组件调用父组件的方法并传递数据注意:子组件标签中的时间也不区分大小写要用“-”隔开 子组件: <template> <button @click=&quo ...