【React】01-React 入门到放弃系列

01-React 入门

  • 背景
  • 入门
    • 学生成绩录入的表单
  • 小结


背景

由于捣鼓一些项目需要用到React,找了一些文档入门实践了一番。本篇文章以一个学生成绩录入的表单为例子,记录React 入门的一些基础操作。

入门

该操作的前提是本地安装了NodeJS环境。根据官网给的例子,我们使用如下命令初始化项目

npx create-react-app react4j

目录结构如下:

react-practice
├── react4j
│   ├── public
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   ├── logo192.png
│   │   ├── logo512.png
│   │   ├── manifest.json
│   │   └── robots.txt
│   ├── src
│   │   ├── App.css
│   │   ├── App.js
│   │   ├── App.test.js
│   │   ├── index.css
│   │   ├── index.js
│   │   ├── logo.svg
│   │   ├── reportWebVitals.js
│   │   └── setupTests.js
│   ├── README.md
│   ├── package-lock.json
│   ├── package.json
└── list.md

● 目录 src :React 应用源码存放的目录。
● 目录 public 包含了开发应用时浏览器会读取的文件,其中最重要的就是 index.html。React 将目录 src 中的代码嵌入这个文件,从而浏览器才能运行此文件。
● 文件 package.json 包含了 Node.js/npm 为了建立该应用程序所管理着的文件信息
● manifest.json 文件定义了应用的名称、简称、图标、启动 URL、显示模式、主题颜色和背景色

启动项目,这里我们可以预览:

npm start

关于 index.html,是项目的主页面,这里只定义一个id为root的标签:

<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

关于index.js,这里引入我们的App组件,App组件定义在App.js文件里。

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  // <React.StrictMode>
  //   <App />
  // </React.StrictMode>
  <App subject="Clarice" />
);

关于App.js,由三部分组成:顶部的 import 语句,中间的 App 组件,以及底部的 export 语句。通过export ,我们可以在项目入口的 index.js文件里用 <APP /> 标签直接使用该组件。

这里的函数命名 App 也是React 特殊的命名方式,它使用帕斯卡命名法,如“HelloWorld”,来帮助用户辨认一个 JSX 元素是 React 组件而非普通的 HTML 标签。如果你将函数名“App”改为“app”,你的浏览器会显示错误。

import React from "react";
import logo from "./logo.svg";
import "./App.css";

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer">
          Learn React
        </a>
      </header>
    </div>
  );
}
export default App;


学生成绩录入的表单

  1. 删除多余的文件 App.test.js App.css logo.svg serviceWorker.js setupTests.js
  2. 在App.js 编写UI,这里存储数据先暂时用localStorage存储录入的数据。
import React, { useState, useEffect } from 'react';


const ScoreTable = () => {
  console.log(111)
  const [scores, setScores] = useState([]);
  const [studentName, setStudentName] = useState('');
  const [studentScore, setStudentScore] = useState('');

  useEffect(() => {
    // 从localStorage中读取数据,并设置为初始state值
    const storedScores = localStorage.getItem('scores');
    if (storedScores) {
      setScores(JSON.parse(storedScores));
    }
  }, []);

  useEffect(() => {
    // 每次scores更新后,将数据保存到localStorage中
    localStorage.setItem('scores', JSON.stringify(scores));
  }, [scores]);
  
  const handleNameChange = (e) => {
    setStudentName(e.target.value);
  };

  const handleScoreChange = (e) => {
    setStudentScore(e.target.value);
  };

  const handleAddScore = () => {
    if (studentName && studentScore) {
      const newScore = {
        name: studentName,
        score: studentScore
      };
      setScores([...scores, newScore]);
      setStudentName('');
      setStudentScore('');
    }
  };


  return (
    <div className="todoapp stack-large">
      <h1>学生成绩录入</h1>
      <form>
        <label htmlFor="new-todo-input" className="label__lg">
          学生姓名:
        </label>
        <input
          type="text"
          id="new-todo-input"
          className="input input__lg"
          name="text"
          value={studentName}
          autoComplete="off"
          onChange={handleNameChange}
        />
        <label htmlFor="new-todo-input" className="label__lg">
          学生成绩:
        </label>

        <input
          type="text"
          id="new-todo-input"
          className="input input__lg"
          name="text"
          value={studentScore}
          autoComplete="off"
          onChange={handleScoreChange}
        />

        <button type="submit" className="btn btn__primary btn__lg" onClick={handleAddScore}>
          新增
        </button>
      </form>

      <h2 id="list-heading">名单列表</h2>
      <table>
        <thead>
          <tr>
            <th>姓名</th>
            <th>成绩</th>
          </tr>
        </thead>
        <tbody>
          {scores.map((score, index) => (
            <tr key={index}>
              <td>{score.name}</td>
              <td>{score.score}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}


function App(props) {
  console.log(props)

  return (
    <ScoreTable />
  );
}

export default App;

  1. 编写CSS样式,可以直接copy如下的CSS样式,取代原来的index.css文件:
/* RESETS */
*,
*::before,
*::after {
  box-sizing: border-box;
}
*:focus {
  outline: 3px dashed #228bec;
  outline-offset: 0;
}
html {
  font: 62.5% / 1.15 sans-serif;
}
h1,
h2 {
  margin-bottom: 0;
}
ul {
  list-style: none;
  padding: 0;
}
button {
  border: none;
  margin: 0;
  padding: 0;
  width: auto;
  overflow: visible;
  background: transparent;
  color: inherit;
  font: inherit;
  line-height: normal;
  -webkit-font-smoothing: inherit;
  -moz-osx-font-smoothing: inherit;
  -webkit-appearance: none;
}
button::-moz-focus-inner {
  border: 0;
}
button,
input,
optgroup,
select,
textarea {
  font-family: inherit;
  font-size: 100%;
  line-height: 1.15;
  margin: 0;
}
button,
input {
  overflow: visible;
}
input[type="text"] {
  border-radius: 0;
}
body {
  width: 100%;
  max-width: 68rem;
  margin: 0 auto;
  font:
    1.6rem/1.25 Arial,
    sans-serif;
  background-color: #f5f5f5;
  color: #4d4d4d;
}
@media screen and (min-width: 620px) {
  body {
    font-size: 1.9rem;
    line-height: 1.31579;
  }
}
/*END RESETS*/
/* GLOBAL STYLES */
.form-group > input[type="text"] {
  display: inline-block;
  margin-top: 0.4rem;
}
.btn {
  padding: 2px;
  margin-left: 5px;
  border: 0.2rem solid #4d4d4d;
  cursor: pointer;
  text-transform: capitalize;
}
.btn.toggle-btn {
  border-width: 1px;
  border-color: #d3d3d3;
}
.btn.toggle-btn[aria-pressed="true"] {
  text-decoration: underline;
  border-color: #4d4d4d;
}
.btn__danger {
  color: #fff;
  background-color: #ca3c3c;
  border-color: #bd2130;
}
.btn__filter {
  border-color: lightgrey;
}
.btn__primary {
  color: #fff;
  background-color: #000;
}
.btn-group {
  display: flex;
  justify-content: space-between;
}
.btn-group > * {
  flex: 1 1 49%;
}
.btn-group > * + * {
  margin-left: 0.8rem;
}

.visually-hidden {
  position: absolute !important;
  height: 1px;
  width: 1px;
  overflow: hidden;
  clip: rect(1px 1px 1px 1px);
  clip: rect(1px, 1px, 1px, 1px);
  white-space: nowrap;
}
[class*="stack"] > * {
  margin-top: 0;
  margin-bottom: 0;
}
.stack-small > * + * {
  margin-top: 1.25rem;
}
.stack-large > * + * {
  margin-top: 2.5rem;
}
@media screen and (min-width: 550px) {
  .stack-small > * + * {
    margin-top: 1.4rem;
  }
  .stack-large > * + * {
    margin-top: 2.8rem;
  }
}
.stack-exception {
  margin-top: 1.2rem;
}
/* END GLOBAL STYLES */
.todoapp {
  background: #fff;
  margin: 2rem 0 4rem 0;
  padding: 1rem;
  position: relative;
  box-shadow:
    0 2px 4px 0 rgba(0, 0, 0, 0.2),
    0 2.5rem 5rem 0 rgba(0, 0, 0, 0.1);
}
@media screen and (min-width: 550px) {
  .todoapp {
    padding: 4rem;
  }
}
.todoapp > * {
  max-width: 50rem;
  margin-left: auto;
  margin-right: auto;
}
.todoapp > form {
  max-width: 100%;
}
.todoapp > h1 {
  display: block;
  max-width: 100%;
  text-align: center;
  margin: 0;
  margin-bottom: 1rem;
}
.label__lg {
  display: inline-block;
  line-height: 1.01567;
  font-weight: 300;
  padding: 0.8rem;
  margin-bottom: 1rem;
  text-align: center;
}
.input__lg {
  padding: 1px;
  border: 2px solid #000;
}
.input__lg:focus {
  border-color: #4d4d4d;
  box-shadow: inset 0 0 0 2px;
}
[class*="__lg"] {
  display: inline-block;

  font-size: 14px;
}
[class*="__lg"]:not(:last-child) {
  font-size: 14px;
}
@media screen and (min-width: 620px) {
  [class*="__lg"] {
    font-size: 14px;
  }
}
.filters {
  width: 100%;
  margin: unset auto;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-family: Arial, sans-serif;
  color: #333;
}

table th, table td {
  padding: 8px;
  text-align: left;
  border-bottom: 1px solid #ddd;
}

table th {
  background-color: #f2f2f2;
  font-weight: bold;
}

table tr:nth-child(even) {
  background-color: #f9f9f9;
}

table tr:hover {
  background-color: #e6e6e6;
  cursor: pointer;
}

input[type="text"] {
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}
  1. npm start 预览:

在这里插入图片描述


小结

  1. 本人实践下来,跟原来HTML + JavaScript 最明显的区别就是,React把UI封装到一个个JS函数里面去了。这跟它官网的描述也挺相符的, 通过使用组件最大程度地减少开发人员构建 UI 时发生的错误。。

  2. React 与 JavaScript 的最大区别在于 JSX 语法的使用上。JSX 是在 JavaScript 语法上的拓展,因此类似于 HTML 的代码可以和 JSX 共存。更多资料可以看看官方文档。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/289534.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker入门教程(详解)

Docker容器化 一 入门 1. 引言 &#xff08;1&#xff09;单机部署 场景&#xff1a; 将多个应用部署一台服务器上。 问题 每个应用软件&#xff0c;都会消耗物理资源&#xff0c;共用计算机资源&#xff0c;彼此之间会形成竞争关系。 &#xff08;2&#xff09;多机部署 …

PHP反序列化漏洞利用及修复,示例代码讲解

您提到的PHP反序列化漏洞是一个重要的网络安全问题。在我的网络安全工程师的角色下&#xff0c;我可以提供关于此问题的深入分析。 PHP反序列化漏洞通常发生在当不可信的数据被反序列化时。序列化是将数据结构或对象状态转换为可存储或可传输的格式的过程&#xff0c;而反序列…

Springcloud 微服务实战笔记 Ribbon

使用 Configurationpublic class CustomConfiguration {BeanLoadBalanced // 开启负载均衡能力public RestTemplate restTemplate() {return new RestTemplate();}}可看到使用Ribbon&#xff0c;非常简单&#xff0c;只需将LoadBalanced注解加在RestTemplate的Bean上&#xff0…

AIGC时代-GPT-4和DALL·E 3的结合

在当今这个快速发展的数字时代&#xff0c;人工智能&#xff08;AI&#xff09;已经成为了我们生活中不可或缺的一部分。从简单的自动化任务到复杂的决策制定&#xff0c;AI的应用范围日益扩大。而在这个广阔的领域中&#xff0c;有两个特别引人注目的名字&#xff1a;GPT-4和D…

C/C++汇编学习(二)——学习使用IDA pro

学习使用IDA Pro是一项很有价值的技能&#xff0c;特别是对于那些对逆向工程和软件安全分析感兴趣的人。以下是一些基本步骤和概念&#xff0c;帮助你熟悉IDA Pro的界面和操作。 1. 熟悉IDA Pro界面和基本操作 主界面布局 IDA Pro的主界面包含多个组件&#xff0c;每个组件都…

pytest-yaml 测试平台-4.生成allure报告,报告反馈企业微信、钉钉、飞书通知

前言 定时任务执行完成后生成可视化allure报告&#xff0c;并把结果发到企业微信&#xff0c;钉钉&#xff0c;飞书通知群里。 生成allure报告 添加定时任务 执行完成后生成allure报告 查看报告详情 报告会显示详细的request 和 response 详细信息 也可以查看log日志 …

Vue3-35-路由-路由守卫的简单认识

什么是路由守卫 路由守卫&#xff0c;就是在 路由跳转 的过程中&#xff0c; 可以进行一些拦截&#xff0c;做一些逻辑判断&#xff0c; 控制该路由是否可以正常跳转的函数。常用的路由守卫有三个 &#xff1a; beforeEach() : 前置守卫&#xff0c;在路由 跳转前 就会被拦截&…

kube-promethues配置钉钉告警

kube-promethues配置钉钉告警 前置&#xff1a;k8s部署kube-promethues 一.配置钉钉机器人 打开钉钉的智能群助手&#xff0c;点击添加机器人 选择自定义机器人 勾选加签&#xff0c;复制后保存 复制webhook地址后点击保存 二.编写dingtalk的yaml部署文件 vi dingta…

74HC595驱动数码管程序

数码管的驱动分静态扫描和动态扫描两种&#xff0c;使用最多的是动态扫描&#xff0c;优点是使用较少的MCU的IO口就能驱动较多位数的数码管。数码管动态扫描驱动电路很多&#xff0c;其中最常见的是74HC164驱动数码管&#xff0c;这种电路一般用三极管作位选信号&#xff0c;用…

pytest conftest通过fixture实现变量共享

conftest.py scope"module" 只对当前执行的python文件 作用 pytest.fixture(scope"module") def global_variable():my_dict {}yield my_dict test_case7.py import pytestlist1 []def test_case001(global_variable):data1 123global_variable.u…

人工智能如何重塑金融服务业

在体验优先的世界中识别金融服务业中的AI使用场景 人工智能&#xff08;AI&#xff09;作为主要行业的大型组织的重要业务驱动力&#xff0c;持续受到关注。众所周知&#xff0c;传统金融服务业在采用新技术方面相对滞后&#xff0c;一些组织使用的还是上世纪50年代和60年代发…

华为云Sys-default、Sys-WebServer和Sys-FullAccess安全组配置规则

华为云服务器默认安全组可选Sys-default、Sys-WebServer或Sys-FullAccess。default是默认安全组规则&#xff0c;只开放了22和3389端口&#xff1b;Sys-WebServer适用于Web网站开发场景&#xff0c;开放了80和443端口&#xff1b;Sys-FullAccess开放了全部端口。阿腾云atengyun…

快速搭建知识付费小程序,3分钟即可开启知识变现之旅

产品服务 线上线下课程传播 线上线下活动管理 项目撮合交易 找商机找合作 一对一线下交流 企业文化宣传 企业产品销售 更多服务 实时行业资讯 动态学习交流 分销代理推广 独立知识店铺 覆盖全行业 个人IP打造 独立小程序 私域运营解决方案 公域引流 营销转化 …

使用jieba库进行中文分词和去除停用词

jieba.lcut jieba.lcut()和jieba.lcut_for_search()是jieba库中的两个分词函数&#xff0c;它们的功能和参数略有不同。 jieba.lcut()方法接受三个参数&#xff1a;需要分词的字符串&#xff0c;是否使用全模式&#xff08;默认为False&#xff09;以及是否使用HMM模型&…

unity学习笔记----游戏练习04

一、开发阳光生产功能 向日葵的生产过程需要动画和时间 1.生产动画 选中Sunflower&#xff0c;然后选中窗口再选中 创建新的剪辑开始制作动画&#xff0c;向日葵生产动画的过程是一个从暗到亮然后持续一段时间再到暗的过程。因此只需要在对应的时间改变颜色即可。 为了保证是…

Weblogic安全漫谈(二)

前言 继本系列上篇从CVE-2015-4852入手了解T3协议的构造后&#xff0c;本篇继续分析开启T3反序列化魔盒后的修复与绕过。 Weblogic对于10.3.6推出了p20780171和p22248372用于修复CVE-2015-4852&#xff0c;在补丁详情中又提示了p21984589是它的超集&#xff0c;所以可以直接装…

项目框架构建之2:主机程序的搭建

本文是“项目框架构建”系列之2&#xff0c;要编写一个项目框架&#xff0c;就好像一个操作系统似的&#xff0c;得有一些东西可以搭载项目结构&#xff0c;而.net core的主机框架正是可以实现这一目的的好帮手。 简单介绍一下主机程序&#xff0c;我们生产系统中往往需要构建…

清风数学建模笔记-聚类算法

K-maens算法&#xff1a; 算法的原理&#xff1a; 在论文中时&#xff0c;可以把一些可以流程化的算法的流程图加上去 优点&#xff1a; 缺点&#xff1a; 点容易受异常值的影响&#xff0c;且受影响较大 k-means算法&#xff1a; 使用SPSS进行聚类分析&#xff1a; S默认使用…

【JUC】Synchronized及JVM底层原理

Synchronized使用方式 Synchronized有三种应用方式 作用于实例方法&#xff0c;当前示实例加锁进入同步代码前要获得当前实例的锁&#xff0c;即synchronized普通同步方法&#xff0c;调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置。 如果设置了&#xff0c;执行…

短视频账号矩阵系统saas工具源码技术开发(源头)

一、短视频矩阵系统搭建常见问题&#xff1f; 二、账号矩阵如何打造&#xff1f;&#xff08;企业号、员工号、达人号裂变&#xff09; 三、无人直播解决什么问题&#xff1f; 一、短视频矩阵系统搭建常见问题&#xff1f; 1、抖去推的短视频AI矩阵营销软件需要一定的技术水…