React教程:4 个 useState Hook 示例
摘要: React示例教程。
- 原文:快速了解 React Hooks 原理
- 译者:前端小智
到 React 16.8 目前为止,如果编写函数组件,然后遇到需要添加状态的情况,咱们就必须将组件转换为类组件。
编写
class Thing extends React.Component,将函数体复制到
render()方法中,修复缩进,最后添加需要的状态。
今天,可以使用 Hook 获得相同的功能,并为自己节省了工作时间。在本文中,主要介绍
useStatehook。
useState 做啥子的
useStatehook 允许咱们向函数组件添加状态,我们通常称这些为“ 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 Hooks useState不生效问题
- React Native基础&入门教程:以一个To Do List小例子,看props和state
- 【REACT NATIVE 系列教程之十一】插件的安装、使用与更新(示例:REACT-NATIVE-TAB-NAVIGATOR)
- 【REACT NATIVE 系列教程之十一】插件的安装、使用与更新(示例:REACT-NATIVE-TAB-NAVIGATOR)...
- react+redux教程(五)异步、单一state树结构、componentWillReceiveProps
- react教程(一)——react优势以及组件、state、props介绍
- [React] Use React Context to Manage Application State Through Routes
- 【REACT NATIVE 系列教程之二】创建自定义组件&&导入与使用示例
- 运行React Native示例出现null is not an object (evaluating 'this.state.text')
- React Native基础&入门教程:以一个To Do List小例子,看props和state
- react-native项目使用flatList后state值改变,不重新渲染页面的问题
- React Native 之 State 的ES5 与ES6 写法区别
- 转发:ASP.NET MVC 4与Windows Azure 表、Blobs、队列的教程系列和示例应用程序
- HTML5+开发移动app教程3-mui开发示例
- pyqt4教程之实现半透明的天气预报界面示例
- WebGL自学教程——WebGL示例:4. 让三角形动起来
- React 入门实例教程
- linux下安装protobuf教程+示例(详细)
- react-router-dom示例讲解(十)——路由配置
- 【原创】React实例入门教程(1)基础API,JSX语法--hello world