0301入门-react脚手架-react应用

Posted gaog2zh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了0301入门-react脚手架-react应用相关的知识,希望对你有一定的参考价值。

1 React脚手架安装

1.1 React脚手架概述

React脚手架(React Starter Kit)是一个工具集,用于帮助开发人员快速搭建React应用程序的基本结构。它包括了React应用程序的基本文件和文件夹结构、自动化构建工具、开发服务器、测试工具等,可以大大减少开发人员的工作量。

目前比较流行的React脚手架包括:

  1. Create React App:这是由React团队提供的官方脚手架,它提供了一个简单的方式来创建React应用程序,包括Webpack和Babel等工具的配置,还可以自动化处理构建、测试和部署等任务。
  2. Next.js:这是一个基于React的服务器端渲染框架,提供了一些附加功能,如代码分割、预取、静态文件导出等,可以大大提高React应用程序的性能和SEO。
  3. Gatsby:这是一个静态站点生成器,也是基于React的,它可以将数据源(如Markdown文件、CMS、API等)转换为静态html文件,具有快速加载、SEO友好、可扩展等优点。

这些React脚手架都可以根据开发人员的需求进行定制化配置,以满足特定的项目要求。

我们目前要学习的create-react-app。

1.2 create-react-app安装

  • 第一步:全局安装,命令npm install -g create-react-app
  • 第二步:切换到目的路径,创建项目 create-react-app xxx项目名
  • 第三部:进入项目文件夹 cd xxx项目名
  • 第四部:启动项目 npm start或者yarn start

1.3 React脚手架项目结构

初始化项目结构如下图1.3-1所示:

2 脚手架文件介绍

启动项目,效果图如下2-1所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PIApI7Wl-1680424518550)(/Users/gaogzhen/baiduSyncdisk/study/front/react/note/03scaffold/images/截屏2023-03-30 17.12.39-create-react-app-yarn-start.png)]

项目结构简介如下:

  • node_modules:项目依赖库
  • public:公共资源文件夹
    • favicon.ico:Favicon.ico是一个网站的图标文件,通常在浏览器的地址栏、书签栏、标签页等处显示。该文件用于标识和区分一个网站,是网站品牌识别的重要组成部分之一。
    • index.html:首页
    • logo192.png:适配192logo
    • Logo512png:适配512logo
    • manifest.json:移动端加壳配置
    • robots.txt:Robots.txt是一种位于网站根目录下的文本文件,用于告诉搜索引擎爬虫哪些网页可以被抓取,哪些网页不能被抓取。Manifest.json是一个Web应用程序清单文件,用于描述Web应用程序的元数据信息,如名称、图标、版本号、作者等。该文件可以帮助浏览器了解Web应用程序的相关信息,从而使Web应用程序更像一个本地应用程序。
  • src:资源文件夹
    • App.css:APP组件样式
    • App.js:函数式定义了一个APP组件
    • App.test.js:给APP做测试
    • index.css:入口样式
    • index.js:项目入口
    • logo.svg:logo
    • ReportWebVitals:记录页面性能
    • setupTests.js:组件测试
    • .gitignore:git忽略文件
    • package.json:
    • README.md:首页介绍

3 自定义组件

我们先了解脚手架,通过循序渐进方式,一些暂时用不到的“组件”我们会删减。

脚手架中我们只留下node_modules,空的public和src文件夹,package.json,README.md。

我们在App壳组件中添加2个自定义的组件Hello和Welcome组件。

第一步,public/index.html,代码如下,

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
  <title>React 脚手架</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>
  • 组件容器root必须的,其他为固定结构

第二步,开发入口文件src/index.js,代码如下:

// 引入react核心库
import React from "react";
// 引入react-dom
import ReactDOM from 'react-dom/client'
// 引入App组件
import App from './App'

// 渲染组件到页面
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
  <React.StrictMode>
    <App/>
  </React.StrictMode>
)
  • 都是固定结构,引入App壳组件并渲染

第三步,开发壳组件src\\App.jsx,代码如下:

// 创建外壳组件App
import Component from 'react'
import Hello from './components/Hello'
import Welcome from './components/Welcome'

class App extends Component 
  render() 
    return (
      <div>
        <Hello />
        <Welcome/>
      </div>
    )
  



export default App
  • 文件前缀为index默认为首页或者入口文件,引入的时候只需引入地址到父路径即可;
  • 文件后缀为js或者jsx引入的时候,只需引入路径到文件名即可。

第四步,为了方便管理和隔离,自定义的组件我们统一放在src/components下,文件名为组件名。

  • 创建Hello组件,代码如下

    import Component from 'react'
    // import Ht from './index.css'
    import hello from './index.module.css'
    
    class Hello extends Component 
      render() 
        return (
          <div>
            <h2 className=hello.title>
               hello, reac222
            </h2>
          </div> 
        )
      
    
    
    export default Hello
    
  • 创建Welcome组件,代码如下

    import Component from 'react'
    import wel from './index.module.css'
    // import './index.css'
    
    class Welcome extends Component 
      render() 
        return (
          <div>
            <h2 className=wel.title>
               welcome study react
            </h2>
          </div> 
        )
      
    
    
    export default Welcome
    
  • import Component from ‘react’ 为模块化导入,不是结构赋值语法。

  • 我们使用类式组件

  • 最后需要导出组件,基于模块化开发,需要导入导出。

  • 因为组件最后统一放置在App组件中,所以,如果样式有冲突,我们可以通过样式模块化来隔离

    • 样式的组件化,即定义样式文件后缀由.css改为.module;在使用时,通过import from导入为对象。

文件结构如下图3-1所示:

代码在文章最后仓库中有。

效果如下图3-2所示:

4 vscode中React插件安装

在开发中,有很多固定和重复的代码,比如引入react,react-dom 定义类组件等等。为了提高开发效率,在很多开发工具中,都提供了代码片段(snippets)功能,即在工作区输入助记符,自动生成相应格式的代码。

其中在vscode中,我们可以通过安装如下图4-1所示插件

该插件给我们封装好了很多代码片段,比如敲rcc 对应代码片段为

import React,  Component  from 'react'

export default class 当前文件名 extends Component 
  render() 
    return (
      <div>当前文件名</div>
    )
  


更多代码片段参考官方文档

5 组件化编码流程

  • 组件拆分:拆分组件,抽取组件;
  • 实现静态组件:使用组件实现静态页面效果;
  • 实现动态组件:
    • 动态显示初始化数据
      • 数据类型
      • 数据名称
      • 保存在那个组件中

通过上面对脚手架的学习,我们用脚手架来做个TodoList入门案例。

结语

❓QQ:806797785

⭐️源代码仓库地址:https://github.com/gaogzhen/react-staging.git

参考:

[1]React视频教程[CP/OL].2020-12-15.p49-55.

[2]React官网[CP/OL].

[2]ChatGPT[CP/OL].

React入门3

React入门3

一.React单页应用

1.脚手架使用

标准框架 用户不用操心过多

  • 安装

    之前在学习官方的井字棋的那个教程的时候已经安装过啦

新建两个项目来学习

npx create-react-app react-demo-2
npx create-react-app react-demo-3
  • 建好啦,来看一看目录层级

    • node_modules 自动安装插件

    • public静态目录

      • index.html 工程入口
      • manifest.json 缓存
    • src 项目源码

      • index.js 项目打包执行入口
    • gitigonre

      忽略哪些文件来提交到git

  • package.json

    • start 启动

    • build 打包

    • test 单元测试

    • eject 内置webpack

      可以使用yarn run eject来显示隐藏的配置信息,但这个是不可逆操作

2.编写Hello World

  • 启动项目

    npm start或者yarn start都可以,启动之后修改代码只需要按下ctrl+s就会自动热加载

    启动后在localhost:3000可以看到:

  • 修改App.js

    原本的App.js:

    • 修改

      import logo from './logo.svg';
      import './App.css';
      import React from 'react';
      function App() 
        return (
          <div className="App">
            <h1>hello world</h1>
          </div>
        );
      
      
      export default App;
      
      • 效果

  • 修改样式

    样式和脚本是分离的

    在index.css中修改

    h1
      font-size: 15em;
      color: cornflowerblue;
    
    

  • 修改为sass

    改为App.scss

    SCSS的简介 - 简书 (jianshu.com)

    并在App.js中改为import './App.scss',会报错,

    在终端中输入:

      yarn add node-sass -S
    

    在安装这个插件的时候最好先把项目终止掉,不然对安装可能有影响

    • 修改示例

      • App.js

        import './App.scss';
        import React from 'react';
        function App() 
          return (
            <div className="App">
              <p>哈哈哈哈哈哈哈哈</p>
              <h1>hello world</h1>
            </div>
          );
        
        
      • App.css

        div 
          text-align: center;
          font-size: 1.5em;
          h1 
            font-size: 3em;
            color: cornflowerblue;
          
        
        
      • 效果

3.单页面todo demo

这里遇到了问题,在key和value我设置为不一样时,解构时候会有问题,应该是ES6解构的一些规范之前没有了解过…

  • 一开始用的和之前一样的

    在setState里面key和value都用的一样的

    import './App.scss'
    import React from 'react';
    
    class App extends React.Component 
    
      state = 
        val: '',
        list:[]
      
      handleChange = (event) => 
          let val = event.target.value;
          this.setState(
            val
          )
          
        
    
        handleClick = () => 
          let  val, list  = this.state;
          list.push(val);
          this.setState(
            list
          )
        
      render() 
        const  val, list  = this.state;
        
        return (
        <div>
            <p>嘿嘿</p>
            <h1>Hello React!</h1>
            <input type="text" value=val onChange=this.handleChange />
            <button onClick=this.handleClick>添加Todo事项</button>
            <ul>
              
                list.map((item)=>
                return <li>item</li>;
               )
              
              
            </ul>
        </div>);
      
    
    
  • 改成key和value不一样,下面这段代码是没问题的:

    import './App.scss';
    import React from 'react';
    class App extends React.Component 
    
      constructor(props)   
        super(props);
        this.state = 
          val: '',
          list:[]
        
      
    
      handleChange = (event) => 
        let val_C = event.target.value;
        this.setState(val: val_C);
      
      
      handleAdd = () => 
        let val_A = this.state.val;
        let list_A = this.state.list;
        list_A.push(val_A);
        this.setState(list: list_A);
      
    
      render() 
        const  val, list  = this.state;
    
        return (
          <div>
            <p>试一试</p>
            <h1>Todo清单</h1>
            <input type="text" value=val placeholder="请输入" onChange=this.handleChange />
            <button onClick=this.handleAdd>添加todo事项</button>
            <ul>
              
                list.map((item, index) => 
                  return <li key=index>item</li>
                )
              
            </ul>
          </div>);
      
    
    
    export default App;
    

    但当我把下面的变量使用解构语法来定义的时候

    就会出现如下报错:

    • 想了半天才想到是解构是不是有啥问题

      果真…

      参考这篇文章:JavaScript基础之ES6对象解构赋值 - SegmentFault 思否

      所以改成…👇

      handleAdd = () => 
          let  val:val_A, list:list_A  = this.state;
          list_A.push(val_A);
          this.setState(list: list_A);
        
      

      就好了

      😭😭😭

      另外最后return那里可以先定义个新的数组

      • 修改后的完整代码:

        import './App.scss';
        import React from 'react';
        class App extends React.Component 
        
          constructor(props)   
            super(props);
            this.state = 
              val: '',
              list:[]
            
          
        
          handleChange = (event) => 
            let val_C = event.target.value;
            this.setState(val: val_C);
          
          
          handleAdd = () => 
            let  val:val_A, list:list_A  = this.state;
            list_A.push(val_A);
            this.setState(list: list_A);
          
        
          render() 
            const  val, list  = this.state;
            const liItem =list.map((item, index) => 
                      return <li key=index>item</li>
                    )
            return (
              <div>
                <p>试一试</p>
                <h1>Todo清单</h1>
                <input type="text" value=val placeholder="请输入" onChange=this.handleChange />
                <button onClick=this.handleAdd>添加todo事项</button>
                <ul>
                  
                    liItem
                  
                </ul>
              </div>);
          
        
        
        export default App;
        

所以没啥基础来学框架…咳 就会有各种基础不牢导致的时间浪费,想了半天没想到是那个问题,console控制台报错也没法一下子看出来是解构语法的问题

注意:

如果没有给每个列表中的元素绑定key,console控制台会报warning

4.AntD UI框架使用

Ant Design of React

👉[官方文档](Ant Design of React - Ant Design)

  • 在刚刚那个项目中安装插件

    yarn add antd -S
    
    • 安装完成可以发现package.json里面

  • App.js里面引入组件和样式

    import Input,Button from 'antd'
    import 'antd/dist'
    

    将input改为Input button改为Button 重新加载先前的页面

上面是把整个antd导进来了,会导致加载时间较长,
按需加载需要使用babel-plugin-import

[babel-plugin-import](前端工程化 - 插件 babel-plugin-import 使用指南 - 掘金 (juejin.cn))

  • 上面的框框太长了

    给Input和Button都加一些属性

    const wl =  width: 300 ,height: 30;
        return (
          <div>
            <p>试一试</p>
            <h1>Todo清单</h1>
            <Input type="text" style=wl  value=val placeholder="请输入" onChange=this.handleChange />
            <Button type="primary" onClick=this.handleAdd>添加todo事项</Button>
            <ul>
              
                liItem
              
            </ul>
          </div>);
    

    效果:

  • 看看别的Input输入框样式

    试一试下面这个:

    • 先在class App 上面取子组件

      Search是Input下的子组件

      const Search  = Input.Search
      //或者
      const Search = Input;
      
    • 拿了官方文档里面两个组件来试试

      • 代码

        import './App.scss';
        import React from 'react';
        import  Input, Button  from 'antd';
        import 'antd/dist/antd.css';
        
        
        const Search = Input.Search;
        
        class App extends React.Component 
        
          state = 
              val: '',
              list:[]
            
          handleChange = (event) => 
            let val_C = event.target.value;
            this.setState(val: val_C);
          
          
          handleAdd = () => 
            let  val:val_A, list:list_A  = this.state;
            list_A.push(val_A);
            this.setState(list: list_A);
          
        
          //Search不用像文本框那样变化的时候先获取一个值
          //(UI内部已经封装好,获取了handleChange那个步骤的值
          handleSearch = (value) => 
            let  list: list_S  = this.state;
            list_S.push(value);
            this.setState( list: list_S );
          
          render() 
            const  val, list  = this.state;
            const liItem = list.map((item, index) => 
              return <li key=index>item</li>
            );
            const wl =  width: 300 ,height: 30;
            return (
              <div>
                <p>试一试</p>
                <h1>Todo清单</h1>
                <Input type="text" style=wl  value=val placeholder="请输入" onChange=this.handleChange />
                <Button type="primary" onClick=this.handleAdd>添加todo事项</Button>
                <ul>
                  
                    liItem
                  
                </ul>
                <div>
                  <Search placeholder="input something" style=width:300 onSearch=this.handleSearch/>
                  <Search enterButton="Search" style=width:300 onSearch=this.handleSearch/>
        
                </div>
              </div>);
          
        
        
        export default App;
        
        
      • 注意这个

      • 效果

  • 试试Select组件

    取其子组件

    在循环里实现

        const op = [];
        const liItem = list.map((item, index) => 
          op.push(<Option key=index>item</Option>)
          return <li key=index>item</li>
        );
    
    • 完整代码

      import './App.scss';
      import React from 'react';
      import  Input, Button,Select from 'antd';
      import 'antd/dist/antd.css';
      
      const  Option  = Select;
      const Search = Input.Search;
      
      class App extends React.Component 
      
        state = 
            val: '',
            list:[]
          
        handleChange = (event) => 
          let val_C = event.target.value;
          this.setState(val: val_C);
        
        
        handleAdd = () => 
          let  val:val_A, list:list_A  = this.state;
          list_A.push(val_A);
          this.setState(list: list_A);
        
      
        //Search不用像文本框那样变化的时候先获取一个值
        //(UI内部已经封装好,获取了handleChange那个步骤的值
        handleSearch = (value) => 
          let  list: list_S  = this.state;
          list_S.push(value);
          this.setState( list: list_S );
        
        render() 
          const  val, list  = this.state;
          const op = [];
          const liItem = list.map((item, index) => 
            op.push(<Option key=index>item</Option>)
            return <li key=index>item</li>
          );
          const wl =  width: 300 ,height: 30;
          return (
            <div>
              <p>试一试</p>
              <h1>Todo清单</h1>
              <Input type="text" style=wl  value=val placeholder="请输入" onChange=this.handleChange />
              <Button type="primary" onClick=this.handleAdd>添加todo事项</Button>
              <ul>
                
                  liItem
                
              </ul>
              <div>
                <Search placeholder="input something" style=width:300 onSearch=this.handleSearch/>
                <Search enterButton="Search" style=width:300 onSearch=this.handleSearch/>
                <Select style=width:300>op</Select>
              </div>
            </div>);
        
      
      
      export default App;
      
    • 效果

以上是关于0301入门-react脚手架-react应用的主要内容,如果未能解决你的问题,请参考以下文章

快速入门react

React入门3

React入门3

React 入门学习-- 认识脚手架

React 入门学习-- 认识脚手架

新手入门系列之-React / Vue 应用持续集成Docker 化