React基础第一天-jsx

React 基础

整体介绍

内容介绍

  1. React 概述

  2. JSX

  3. React 组件基础

React 介绍

目标

了解react的基本概念,

是什么

在这里插入图片描述

React 是用于构建用户界面的 JavaScript 库

  • 构建用户界面. User Interface,对咱们前端来说,简单理解为:HTML 页面
  • javscrtipt库。不是框架,是库。
    • vue: 是渐进式的javascript框架
    • react 全家桶是框架
      • react: 核心库
      • react-dom: dom操作
      • react-router:路由,
      • redux:集中状态管理

拓展

  1. 框架背景
    1. react是Facebook(meta) 内部项目
    2. vue是尤雨溪个人作品
    3. angular是goole公司产品
  2. 趋势
    1. react全球第一
    2. vue在国内较多,react也慢慢多了
    3. angular在跨国公司使用较多

react, vue, angular的下载趋势

小结

react是?构建用户界面的js库。

React 特点

目标

了解react的特点

声明式

只需要描述UI看起来时什么样的,就跟写html一样。

用类似于html的语法来定义页面。react中通过数据驱动视图的变化,当数据发生改变react能够高效地更新并渲染DOM。

<div className="app">
    <h1>Hello React! 动态数据变化:{count}</h1>
</div>

组件化

组件是react中最重要的内容

组件用于表示页面中的部分内容

组合、复用多个组件,就可以实现完整的页面功能

学习一次,随处使用

使用react/rect-dom可以开发Web应用

使用react/react-native可以开发移动端原生应用(react-native)RN

使用react可以开发VR(虚拟现实)应用(react/react360)

小结

从你的角度看 React 特点:工资高、大厂必备(阿里,字节,百度、腾讯、京东、蚂蚁金服、拼多多、美团、外企、银行等都在用)

react的三个特点:

  • 声明式
  • 组件化
  • 一次学习多次使用

React脚手架-从零开始创建项目

目标

掌握react脚手架的使用

脚手架create-react-app

官方工具: create-react-app

创建方式1

  1. 全局安装脚手架工具包

    命令:npm i -g create-react-app

  2. 用脚手架工具来创建项目

    命令:create-react-app your-project-name

创建方式2

直接使用npx来创建项目

命令:

npx create-react-app your-project-name

解释:

  • npx create-react-app 是固定命令,create-react-app 是 React 脚手架的名称
  • your-project-name 表示项目名称,可以修改

拓展

  1. npx 是 npm v5.2 版本新添加的命令,用来简化 npm 中工具包的使用

  2. 没有npx之前:

    1. 全局安装npm i -g create-react-app
    2. 在通过脚手架的命令来创建 React 项目
  3. 有了npx之后

    npx 调用最新的 create-react-app 直接创建 React 项目

React脚手架-了解项目的工作方式

目标

认识react项目目录结构

启动项目

npm start

目录src

在这里插入图片描述

说明:

  • src 目录是我们写代码进行项目开发的目录
  • index.js是入口文件
  • 查看 package.json 两个核心库:reactreact-dom(脚手架已经帮我们安装好,我们直接用即可)

调整

  1. 删除 src 目录下的所有文件

  2. 创建src/index.js, 内容如下:

    console.log('我的第一个react项目跑起来啦')
    

查看效果

在浏览器控制台中查看效果

工作原理

webpack会实时自动打包,并把代码嵌入到public/index.html文件中,并执行。

小结

  1. 我们在哪里写代码?

  2. 入口文件是?

第一份react程序

目标

了解react程序的基本步骤

步骤

  1. 导入包: React, ReactDOM
  2. 创建 react元素
  3. 渲染元素到某个dom上

示例

在页面上创建一个h1标题。

代码:index.js

// 导入react和react-dom
import React from 'react'
import ReactDOM from 'react-dom'

// 创建元素
const title = React.createElement('h1', {id:'box'}, 'hello react')

// 渲染react元素
ReactDOM.render(title, document.getElementById('root'))

效果:

在浏览器中查看

理解react-dom

rect包 提供必要功能来定义react组件。

react-dom包用来将react组件渲染到dom中。

react-native包 用来将react组件渲染到IOS和Android程序中。

package.json

在这里插入图片描述

小结

react包的作用是?

react-dom包的作用是?

一个react程序的三个步骤是?

练习

目标

用脚手架工具创建一个名为react-demo的项目,并在页面上渲染如下dom结构

<div>
  <h1>
    第一个react程序
  </h1>
  <p>
    react是用来构建用户界面的js库
  </p>
</div>

要点

React.createElement的格式:

React.createElement('标签名',{标签上的属性1:值1},子元素1,子元素2)

参考

https://zh-hans.reactjs.org/docs/react-api.html#createelement

JSX介绍-基本使用

问题导入

createElement的效率太低了。

  • 繁琐不简洁
  • 不直观,无法一眼看出所描述的结构
  • 不优雅,开发体验不好

在这里插入图片描述

目标

了解JSX的定义,了解它的工作过程

JSX是什么

JSX:是 JavaScript XML的缩写。

  • 在 JS 代码中书写 XML 结构

  • React用它来创建 UI(HTML)结构

理解:我们之前用html写页面,现在是用jsx来写页面

jsx示例

// 导入react和react-dom
import React from 'react'
import ReactDOM from 'react-dom'

// jsx创建元素
const list = <ul><li>html</li><li>js</li><li>css</li><ul>

// 渲染react元素
ReactDOM.render(list, document.getElementById('root'))

优势

  • 采用类似于 HTML 的语法,降低了学习成本,会 HTML 就会 JSX
  • 充分利用 JS 自身的能力来创建 HTML 结构。比如,利用 JS 数组的 map 方法创建列表结构

拓展:JSX是如何工作的?

babel在线使用

jsx —babel—> React.createELement

在这里插入图片描述

小结

  1. jsx是什么的简写?
  2. jsx的作用是?
  3. jsx相比createElement的好处?
  4. 为啥在js代码中可以直接写jsx的代码?

JSX的注意事项

目标

掌握JSX的5个注意事项

内容

  1. jsx必须要有一个根节点
  2. 属性名不能用js中的关键字。例如class, for
  3. 单标签要闭合
  4. 换行建议使用( )包裹
  5. 老版本(16.8)先引入react才能使用jsx

jsx必须要有一个根节点

虚拟根节点

有两种格式

格式1:<> xxx </>

import ReactDOM from 'react-dom'

const title = <> <h1>Hello React</h1><p>p标签</p> </>

ReactDOM.render(title, document.querySelector('#root'))

格式2:<React.Fragment> xxx </React.Fragment>

import ReactDOM from 'react-dom'

const title = <React.Fragment> <h1>Hello React</h1><p>p标签</p> </React.Fragment>>

ReactDOM.render(title, document.querySelector('#root'))

属性名不能用js中的关键字

例如class, for

  • class -> className
  • for ->htmlFor

单标签要闭合

  • <input> —> <input />

老版本(16.8)先引入react才能使用jsx

理解引入react的作用(提供createElement的功能)

老版本中不引入就会报错React must be in scope when using JSX

换行建议使用()包裹

const content = (
	<div>
  	<h1>xxx</h1>
  </div>
)

JSX-嵌入表达式

导入

通过上面的学习,我们已经可以使用jsx来描述一段静态结构了,更多的情况下,我们需要动态的结构。例如,在页面上输出一个随机值

import ReactDOM from 'react-dom'

const num = Math.random()
const title = (<div>
               		随机值:num
               </div>)

ReactDOM.render(title, document.querySelector('#root'))

目标

会在 JSX中嵌入表达式

嵌入表达式的格式

{ JS 表达式 }

例如:

import ReactDOM from 'react-dom'

const num = Math.random()
const title = (<div>
               		随机值:{ num }
               </div>)

ReactDOM.render(title, document.querySelector('#root'))

大括号是一种特殊的语法,让 JSX 解析器知道它需要将它们之间的内容解释为 JavaScript代码 而不是字符串

作用:执行{}内部的代码,并输出结果。

嵌入表达式的位置

  1. 属性值

    const logo = 'https://create-react-app.dev/img/logo.svg'
    <img width="80" src={logo} />
    
  2. 内容

    const name = '小芳'
    <div>{name}</div>
    

单花括号中可以写什么?

可以写

  1. 表达式

    定义:数据类型和运算符的组合(可以单独出现数据类型,也可以数据类型+运算符的组合)

    特点:有值(或者能够计算出一个值); 能被console.log()

  2. 其他的jsx表达式

  3. 注释

不可以写

  1. 对象
  2. js语句:if 语句/ switch-case 语句/ 变量声明语句

示例

import React from 'react'
import ReactDOM from 'react-dom'

const girl = {
  name: '小芳',
  age: 19,
  logo: 'https://create-react-app.dev/img/logo.svg',
  skills: ['唱歌', '收稻子']
}

const f1 = () => {
  return <i>{girl.skills.join(',')}</i>
}
const baseInfo = (
  <div>
    姓名: {girl.name}
    妙龄: {girl.age}
  </div>
)

const content = (
  <div style={{ padding: 50 }}>
    <h1>jsx-表达式</h1>

    {/* 1. {} 可以用在内容上 */}

    {/* {}可以包其他的jsx */}
    {baseInfo}

    {/* {}可以包表达式 */}
    <p>爱好:{girl.skills}</p>
    <p>字符串:{'abc'}</p>
    <p>字符串:{'{'}</p>
    <p>数组:{[1, 2, 3]}</p>
    <p>数值:{100}</p>
    <p>函数:{f1()}</p>
    <p>算数表达式:100/2={100 / 2}</p>
    <p>
      三元表达式:{girl.age < 28 ? '芳龄' : '年龄'} {girl.age}
    </p>

    {/* 2. {}可以用在属性值上 */}
    <p className={['class1', 'class2'].join(' ')}>类名组合</p>
    <img width="80" src={girl.logo} />

    {/*
    下面是错误的示范
    不能输出对象,不能使用语句
    <p>{{ a: 1 }}</p>
    <p>{var a =1 }</p> */}
  </div>
)
ReactDOM.render(content, document.getElementById('root'))

小结

  1. {}的作用是?
  2. {}可以嵌入在哪里?
  3. {}内部可以写什么,不可以写什么?

JSX-条件渲染

目标

掌握条件渲染,能根据是否满足条件生成 HTML 结构

实现方式

  • if/else
  • 三元运算符
  • 逻辑与(&&)运算符
  • switch case

示例

简单情况-用三元表达式

const flag = 0
const content = (<div>{flag ? '达成' : '没有达成'}</div>)

简单情况-用逻辑与

const isLogin = true
const content = (<div>{ isLogin && '您登录了'}</div>)

复杂情况-使用额外的函数

const loadData = (isLoading) => {
  if (isLoading) {
    return <div>数据加载中,请稍后...</div> 
  } else {
    return <div>数据加载完成,此处显示加载后的数据</div>
  }
}
const content = <div>{loadData(true)}</div>

小结

简单条件渲染使用________ 和 _____

复杂的条件渲染使用函数,在函数内部通过if,else,swich, case来显示内容

JSX-列表渲染

目标

在JSX中使用数组的map方法来生成列表结构

场景

从后端取回来的数据保存在数组中,需要用列表展示。这里的数组如下:

const skills = [
  { id: 1, name: 'html' }, 
  { id: 2, name: 'css' }, 
  { id: 3, name: 'js' }
]

我们要生成的dom结构如下:

<ul>
  <ol>技能1:html</ol>
  <ol>技能2:css</ol>
  <ol>技能3:js</ol>
</ul>

如何实现呢?

笨方法

直接定义一个数组,每个元素都是一个jsx结构

const skills = [<ol>技能1:html</ol>, <ol>技能2: css</ol>, <ol>技能3: js</ol>]

const content = <ul>{skills}</ul>

ReactDOM.render(content, document.getElementById('root'))

用map

完整格式

// 完整格式
const t = skills.map(function(item) {
  return <ol>技能{item.id}: {item.name}</ol>
})

const list = <ul>{t}</ul>

简写格式

const list = (
  <ul>
    {skills.map(item => <ol>技能{item.id}: {item.name}</ol>)}
  </ul>
)

小结

作用:重复生成相同的 HTML 结构。

列表渲染中的key

目标

了解key的作用,能正确给循环渲染项添加key

了解key的作用

React 内部用来进行性能优化时使用的,在最终的HTML结构中是看不到的。

性能优化

例如,数据如下

const songs = [
  { id: 1, name: '痴心绝对' }, 
  { id: 2, name: '像我这样的人' }, 
  { id: 3, name: '南山南' }
  { id:4, name: 'abc'}
]

生成的dom

<ul>
  <li>排名:1 - 歌名:痴心绝对</li>
  <li>排名:2 - 歌名:想我这样的人</li>
  <li>排名:3 - 歌名:南山南</li>
</ul>

如果添加一条数据,则视图也要随之更新,而更新的逻辑是:前三条正常保留,而重新添加第四条。

如何设置key

如果数据中有一个唯一的属性值,就可以使用这个属性来当做key

如果没有,就可以用索引值

练习-用jsx来写结构

目标

按要求完成列表渲染

内容

// 下面是数据 
const list = [
  { id: 1, name: '武汉黑马前端64期', salary: 11000 },
  { id: 2, name: '武汉黑马前端66期', salary: 15000 }
]

// 下面是要求生成的结构

/*
  <ul>
    <li>
      <h3>班级:武汉黑马前端64期</h3>
      <p>工资:11000</p>
    </li>
    <li>
      <h3>班级:武汉黑马前端66期</h3>
      <p>工资:15000</p>
    </li>
  </ul>
*/

JSX 样式处理

目标

掌握在jsx中使用行内样式和类名样式

行内样式 - style

格式

<dom元素 style={ {css属性1:值1,css属性2:值2} }></dom元素>

示例

// 行内样式
<h1 style={ {color: 'red', width: 200, backgroundColor: 'black'} }>
  我是黑底红字的h1
</h1>

要点:

  1. 为啥有两个{{ }}
    1. 外层的{}表示 要开始写js了
    2. 内层的{}表示是一个对象
  2. 属性名是小驼峰格式 (background-color ===> backgroundColor)
  3. 属性值是字符串, 如果单位是px,可以简写数值

使用 className

要点

  • 用className(不是class)定义类名
  • 把样式写在额外的.css文件中,然后引入.css文件
import './index.css'

// 类名
<h1 className="title">
  我是黑底红字的h1
</h1>

补充建立.css

.title{
  color: red;
  width: 200px;
  background-color: black;
}

小结

jsx中的样式:

  • 行内: style={{对象,小驼峰}}
  • 外部: className

JSX 整体总结

  • React 使用 JSX 来编写 UI(HTML)
  • React 完全利用 JS 语言自身的能力来增强 UI 的编写 - 能用 JS 来实现的功能绝不会增加一个新的 API
  • 现在,就可以使用 React 来编写任意 UI 结构了

案例

目标

综合使用jsx的知识,用给定的数据+基本结构和样式渲染成如下效果。

导入本地图片

<img src="./images/avater.png" 不一定能被脚手架工具处理。

如果发现显示不出来,就

import avatar from './images/avatar.png'

<img src={avatar }/>

参考代码

import ReactDOM from 'react-dom'
import './index.css'
import avatar from './images/avatar.png'
// 任务
// 下面有一份数据,需要渲染到页面上
const state = {
  // hot: 热度排序  time: 时间排序
  tabs: [
    {
      id: 1,
      name: '热度',
      type: 'hot'
    },
    {
      id: 2,
      name: '时间',
      type: 'time'
    }
  ],
  active: 'time',
  list: [
    {
      id: 1,
      author: '刘德华',
      comment: '给我一杯忘情水',
      time: '2021-10-10 09:09:00',
      img:
        'https://y.qq.com/music/photo_new/T001R300x300M000003aQYLo2x8izP.jpg?max_age=2592000',
      // 1: 点赞 0:无态度 -1:踩
      attitude: 1
    },
    {
      id: 2,
      author: '周杰伦',
      comment: '听妈妈的话',
      time: '2021-10-11 09:09:00',
      img:
        'https://y.qq.com/music/photo_new/T001R500x500M0000025NhlN2yWrP4.jpg?max_age=2592000',
      // 1: 点赞 0:无态度 -1:踩
      attitude: 0
    },
    {
      id: 3,
      author: '陈奕迅',
      comment: '十年',
      time: '2021-10-11 10:09:00',
      img:
        'https://y.qq.com/music/photo_new/T001R500x500M000003Nz2So3XXYek.jpg?max_age=2592000',
      // 1: 点赞 0:无态度 -1:踩
      attitude: -1
    }
  ]
}

const element = (
  <div className="App">
    <div className="comment-container">
      {/* 评论数 */}
      <div className="comment-head">
        <span>{state.list.length} 评论</span>
      </div>
      {/* 排序 */}
      <div className="tabs-order">
        <ul className="sort-container">
          {state.tabs.map((item) => (
            <li
              className={item.type === state.active ? 'on' : ''}
              key={item.id}>{item.name}排序
            </li>
          ))}
          {/* <li className="on">按  热度  排序</li>
          <li>按  时间   排序</li> */}
        </ul>
      </div>

      {/* 添加评论 */}
      <div className="comment-send">
        <div className="user-face">
          <img className="user-head" src={avatar} alt="" />
        </div>
        <div className="textarea-container">
          <textarea
            cols="80"
            rows="5"
            placeholder="发条友善的评论"
            className="ipt-txt"
          />
          <button className="comment-submit">发表评论</button>
        </div>
        <div className="comment-emoji">
          <i className="face" />
          <span className="text">表情</span>
        </div>
      </div>

      {/* 评论列表 */}
      <div className="comment-list">
        {state.list.map((item) => (
          <div key={item.id} className="list-item">
            <div className="user-face">
              <img className="user-head" src={item.img} alt="" />
            </div>
            <div className="comment">
              <div className="user">{item.author}</div>
              <p className="text">{item.comment}</p>
              <div className="info">
                <span className="time">{item.time}</span>
                {/* 喜欢 */}
                <span className={item.attitude === 1 ? 'like liked' : 'like'}>
                  <i className="icon" />
                </span>
                {/* 不喜欢 */}
                <span className={item.attitude === -1 ? 'hate hated' : 'hate'}>
                  <i className="icon" />
                </span>
                <span className="reply btn-hover">删除</span>
              </div>
            </div>
          </div>
        ))}
      </div>
    </div>
  </div>
)

ReactDOM.render(element, document.getElementById('root'))

练习

在这里插入图片描述

拓展1-环境配置-引入eslint

目标

在react项目中配置eslint,并启用保存自动格式化功能

思路

  1. 在项目中安装eslint
  2. 用eslint的init命令创建eslint配置文件
  3. 设置vscode的自动保存格式化

步骤

  1. npm i eslint typescript -D

  2. 在项目根目录,运行npx eslint --init

    1. 按交互提示安装相关插件
      1. 选择是否使用 TypeScript, 选择是
    2. 它会自动生成eslint的配置文件
  3. 设置vscode的自动保存格式化

在这里插入图片描述

代码

在项目根目录下,补充配置文件:.vscode\settings.json,其内容如下:

{
  "eslint.run": "onType",
  "eslint.options": {
    "extensions": [".js", ".vue", ".jsx", ".tsx"]
  },
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  }
}

拓展2-环境配置-引入prettier-now

eslint并不能深入到jsx代码中来格式化,所以需要额外的工具。

prettier-now

是prettier项目的分支,具备和prettier一样的功能,不过,它允许使用更多的配置项。在vscode的插件库中,同时有prettier-now和prettier,在安装时,请不要安装错了。

步骤

  1. 安装vscode插件prettier-now
  2. 补充配置

代码

.vscode\settings.json

{
  "eslint.run": "onType",
  "eslint.options": {
    "extensions": [".js", ".vue", ".jsx", ".tsx"]
  },
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },

  // 编辑器设置 - 保存时做格式化
  "editor.formatOnSave": true,
  // 编辑器设置 - 默认采用prettier-now做格式化
  // 如果使用的是prettier,这的设置应该是 esbenp.prettier-vscode
  "editor.defaultFormatter":"remimarsal.prettier-now",

  // 控制缩进
  "prettier.useTabs": false, // 缩进不使用tab,使用空格 
  "prettier.tabWidth": 2, // 缩进字节数
  
  // 函数声明时小括号前后要加空格
  // 如果你使用prettier这一项是不能做选择的,导致和eslint默认配置的冲突
  // 可以在百度中搜到很多的记录: https://www.baidu.com/s?wd=prettier%20%E5%87%BD%E6%95%B0%E7%A9%BA%E6%A0%BC
  "prettier.spaceBeforeFunctionParen": true,

  // react的jsx让>与结束标签同行
  "prettier.jsxBracketSameLine": true,
  "prettier.bracketSpacing": false, // 去掉数组内部前后的空格
  "prettier.semi": false, // 不要给语句加;
  "prettier.singleQuote": true, // 采用单引号
  "prettier.trailingComma": "none", // 不要尾随逗号,
  "prettier.printWidth": 80, // 每行超过80列就换行

  // 在.js中,写div按下tab就可以自动补全,而不需要写<div再补全
  "emmet.includeLanguages": {
    "javascript": "javascriptreact"
  }
}

react 17之后,页面上使用jsx时,可以省略import React

在16的版本中,页面上使用jsx,必须import react

在这里插入图片描述

拓展3-大厂的ui库

  1. DIDI
    1. vue移动端 Cube UI
  2. JD
    1. vue移动端: NUTUI
  3. 饿了么
    1. vuePC端 elementUI
  4. 蚂蚁
    1. react PC端antdesign
    2. vue PC端 vue
  5. 字节
    1. react PC端 arco
    2. vue3 PC端arco

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值