前言

在上一章 React 简单教程-3-样式 中我们建立了一个子组件,并稍微美化了一下。在另一篇文章 React 简单教程-3.1-样式之使用 tailwindcss 章我们使用了 tailwind 来写样式,以后我代码里的样式都会使用 tailwind 来写。

这一章,我将给我们的子组件加一个按钮,以实现交互的功能。

什么功能?

我们现在的子组件如下图:

现在它没有交互功能,我想给他的灰色按钮加一个点击事件,点击后将内容收起,如下:

实现

首先,我们的灰色按钮,现在只是一个 span 元素,需要先将它换成 button 元素,样式不变,我们只需要直接将标签从 span 换成 button 就可以了。

export function Displayer(props: { name: string, content: string }) {
const name = props.name;
const content = props.content;
return (
<div className="bg-gray-800 text-white p-2 m-2 rounded-lg">
<div className="nav">
<span className="btn-red"></span>
<span className="btn-yellow"></span>
{/* 灰色按钮 */}
<button className="btn-gray"></button>
</div>
<div className="body">
<div>{name}</div>
<div>{content}</div>
</div>
</div>
);
}

之后添加点击事件。就跟我们在 html 元素上添加一样,在按钮的 onclick 里绑定事件,React 也一样,但是写法需要是小驼峰写法:onClick,React 的组件所有属性都是小驼峰下发。我们在组件里定义一个方法用来处理这个按钮的事件,然后将方法赋给 onClick 属性:

export function Displayer(props: { name: string, content: string }) {
// 忽略
// 定义的处理方法
function handleClick() {}
return (
<div className="bg-gray-800 text-white p-2 m-2 rounded-lg">
{/* 忽略 */}
{/* 灰色按钮 */}
<button className="btn-gray" onClick={handleClick}></button>
{/* 忽略 */}
</div>
);
}

我们绑定方法的时候,方法名要写在花括号里,根据规范,处理事件的方法一般以 handle 开头。现在我们的方法 handleClick 里没有任何实现。

接下来,要隐藏我们的内容元素,可以直接使用 hidden 属性来隐藏:

<div className="body" hidden></div>

但是这是静态的操作,我们要在点击按钮后动态隐藏。我们会想到定义一个变量 isHidden,将变量赋给要隐藏的元素:

<div className="body" hidden="{isHidden}"></div>

通过按钮事件,将值变为 true,当值为 true 时,元素就隐藏了。但是如果你试一遍的话,就会发现是不起效的。因为你只是改变了变量,没有重绘界面,所以界面是不会变化的。

在 React 里需要怎么做呢?

使用 useState hook

什么是 hook?在本文中,我不打算详细介绍什么是 hook(下一章里我会介绍),但是我想先让你感受下 hook。在 react 中,你会经常看到以 use 开头的方法,你可以认为这些方法就是 hook,是 React 提供的用于实现一些特性的功能。这里我们将使用这个 hook 来解决上面的问题。

hook useState 是干什么的?跟随下面一边写一边感受一下。

导入 useState 并使用:

//  导入 hook
import { useState } from "react"; export function Displayer(props: { name: string, content: string }) {
// 使用 hook
const [hidden, setHidden] = useState(false);
}

看示例,hook 就是一个方法,也跟使用方法一样使用。在示例中,useState(false) 返回了一个数组,数组中的第一个参数是一个变量,第二个参数是修改这个变量的方法,使用 useState 可以传入这个变量的默认值,在示例中,我传入了 false,根据类型推断,数组中的第一个参数被推断出是 boolean 类型。

从这里,你应该能够看出,hook useState 的作用是创建变量。和一般变量的不同的地方在于,它提供了修改这个变量的方法 setHidden,这个修改的方法,特点在于,它会重绘这个组件!

也就是说,当我们调用 setHidden,传入新的值,修改了变量后,它会让这个组件的界面更新一遍,这样,组件的界面就可以发生变化了!

在我们的子组件中感受一下,使用 useState 创建的变量来代替我们的 isHidden 变量,代码如下:

export function Displayer(props: { name: string, content: string }) {
// 忽略
const [hidden, setHidden] = useState(false); function handleClick() {
setHidden(true);
} return (
<div className="bg-gray-800 text-white p-2 m-2 rounded-lg">
<div className="nav">
{/* 忽略 */}
<button className="btn-gray" onClick={handleClick}></button>
</div>
<div className="body" hidden={hidden}>
{/* 忽略 */}
</div>
</div>
);
}

在上面的代码上,按钮 buttononClick 绑定了处理函数,函数里调用了 setHidden(true);,将 hidden 的值设为 true,并触发了重绘,重绘时,因为 hidden 的值为 true,内容元素的 hidden 被触发,内容元素隐藏。

就这样,实现了我们点击隐藏的效果。亲手试一试,感受一下 hook。

扩展习题

你能不能扩展这个功能,让按钮再点击一下,就展开内容元素?

总结

  1. 本文章我们学会了按钮元素点击事件的用法。其他事件的用法也大同小异,比如 onChang
  2. 学会了第一个 hook:useState,并知道这个 hook 起到了什么作用。

在下一章中,将介绍其他几个常用 hook。

React简单教程-4-事件和hook的更多相关文章

  1. React简单教程-6-单元测试

    前言 我想大部分人的前端测试,都是运行项目,直接在浏览器上操作,看看功能正不正常.虽然明明有测试库可以使用,但是因为"要快"的原因,让好好做测试变成了一件影响效率的事. 因为这种无 ...

  2. React简单教程-3-样式

    前言 在上一章 React 简单教程-2-ts 和组件参数 中我们新建的子组件 Displayer 没有样式,显得平平无奇,这一篇我们将给他美化一下. CSS 文件 一般的做法,是在你的组件级目录下新 ...

  3. React简单教程-2-ts和组件参数

    前言 在上一章:React 简单教程-1-组件 我们知道了 React 的组件是什么,长什么样,用 js 和 HTML 小小体验了一下组件.在这一章,我们将使用 typescript(简称 ts) 来 ...

  4. React简单教程-4.1-hook

    前言 虽然我们简单感受了一下 useState 的用法,但我想你还是对 React 里的 hook 迷迷糊糊的.本文我们将明确下 React 的概念. HOOK 前生今世 在我示例中,写的 React ...

  5. React简单教程-1-组件

    前言 React,Facebook开发的前端框架.当时Facebook对市面上的前端框架都不满意,于是自己捣鼓出了React,使用后觉得特别好用,于是就在2013年开源了. 我也用React开发了一个 ...

  6. React简单教程-5-使用mock

    前言 一个前后端分离的项目,前端人员需要对接后端的接口.如果在后端的接口没有开发好,或者没有测试版可以对接的情况下,前端人员也不能坐等后端接口写好后再开始开发. 一个项目的,理想情况下接口的规范应该是 ...

  7. React简单教程-3.1-样式之使用 tailwindcss

    前言 本文是作为一个额外内容,主要介绍 tailwindcss 的用法 tailwindcss 是一个功能类优先的 CSS 框架,我在以前的文章里有描述为什么使用功能类优先:为什么我在 css 里使用 ...

  8. react+redux教程(五)异步、单一state树结构、componentWillReceiveProps

    今天,我们要讲解的是异步.单一state树结构.componentWillReceiveProps这三个知识点. 例子 这个例子是官方的例子,主要是从Reddit中请求新闻列表来显示,可以切换reac ...

  9. react 入门教程 阮一峰老师真的是榜样

    -  转自阮一峰老师博客 React 入门实例教程   作者: 阮一峰 日期: 2015年3月31日 现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Nati ...

随机推荐

  1. EL表达式详解(常用表达式以及取值)

    EL表达式 学习总结 一. El表达式概念 二. El中的表达式 1. 算术表达式 2. 比较表达式 3. 逻辑表达式 4. 三元表达式 5. 判空表达式 三.EL 从四个作用域中取值 1. 概念 2 ...

  2. linux压缩打包、定时任务

    压缩打包 gzip压缩 win中的压缩包:zip rar Linux常见的压缩包有哪些? gzip bzip2 1.gzip压缩 压缩命令:gzip [压缩文件] 解压命令:gzip -d [压缩包] ...

  3. QT的MYSQL驱动库编译

    QT的MYSQL驱动库编译 需要准备QT的源码Src,此次编译64位 在QTCreator中打开mysql.pro 修改两个pro 文件,下图为改好 1.mysql.pro TARGET = qsql ...

  4. GopherCon SG 2019 "Understanding Allocations" 学习笔记

    本篇是根据 GopherCon SG 2019 "Understanding Allocations" 演讲的学习笔记. Understanding Allocations: th ...

  5. Nuxt.js(二、解决首屏速度与SEO)

    Nuxt.js(二.解决首屏速度与SEO) 1.普通的Vue SPA初始化加载速度很慢 在传统的web应用中,当用户请求一个页面时,服务器直接返回一个html文件,浏览器直接渲染出来.但是,在vue应 ...

  6. 【课程汇总】OpenHarmony全场景Demo数字管家系列课(附链接)

    小孩放学了,做作业的时间到,窗帘.护眼灯自动打开,关掉电视和扫地机,给小孩一个安静舒适的学习环境:碰到学习难题,可以随时请求你的远程指导:晚上回家休息了,选择舒适的氛围灯,伴随着睡眠音乐进入梦乡:出门 ...

  7. 纯css 实现充电动画

    <template>   <div class="container">     <div class="header">& ...

  8. 【简单dfs】Bubble Cup 14 - Finals Online Mirror (Unrated, ICPC Rules, Teams Preferred, Div. 2), problem: (J) Robot Factory,

    传送门  Problem - 1600J - Codeforces 题目   题意 给定n行m列, 求每个连通块由多少格子组成,并将格子数从大到小排序输出 对于每个格子都有一个数(0~15),将其转化 ...

  9. 使用Lua 脚本实现redis 分布式锁,报错:ERR Error running script (call to f_8ea1e266485534d17ddba5af05c1b61273c30467): @user_script:10: @user_script: 10: Lua redis() command arguments must be strings or integers .

    在使用SpringBoot开发时,使用RedisTemplate执行 redisTemplate.execute(lockScript, redisList); 发现报错: ERR Error run ...

  10. 算法基础⑨搜索与图论--存在负权边的最短路--bellman_ford算法

    bellman-ford算法 给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环, 边权可能为负数. 请你求出从 1 号点到 n 号点的最多经过 k 条边的最短距离,如果无法从 1 号点走到 ...