程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

React基础知识 [ 新手上路学这一篇就够了 ]

发布于2021-05-30 12:25     阅读(1041)     评论(0)     点赞(9)     收藏(1)


一、什么是React?

React是一个用于构建用户界面的javaScript库,起源于facebook的内部项目,后续在13年开源了出来

1.特点

  • 声明式:只需要描述UI看起来是什么样式,就跟写HTML一样,React负责渲染UI
  • 基于组件:组件是React最重要的内容,组件表示页面中的部分内容
  • 适用范围广:使用React可以开发Web应用,使用React可以开发移动端,可以开发VR应用

2.React基本使用

新建挂载点

<div id="root"></div>

React的引用

<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

创建React元素并渲染到页面

<script>
  // 参数一:元素名称;参数二:元素属性;参数三:元素的子节点
  const title = React.createElement('h1', null, 'Hello React')
  // 参数一:要渲染的react元素;参数二:挂载点
  ReactDOM.render(title, document.getElementById('root'))
</script>

在这里插入图片描述

二、React脚手架

  • 脚手架是开发现代Web应用的必备
  • 充分利用 Webpack,Babel,ESLint等工具辅助项目开发
  • 零配置,无需手动配置繁琐的工具即可使用
  • 关注业务,而不是工具配置

1.使用React脚手架初始化项目

初始化项目

npx create-react-app myreact
  • npx 目的:提升包内提供的命令行工具的使用体验
  • create-react-app 这个是脚手架名称 不能随意更改
  • myreact 自己定义的项目名称不能大写
    启动项目
npm start

在这里插入图片描述

2.脚手架中使用React

删除 src 目录下的 所有文件,然后创建 index.js 文件
导入react和react-dom两个包

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

创建元素

let h1 = React.createElement('h1', null, 'Hello 初辰')

渲染到页面

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

在这里插入图片描述

三、JSX的使用

1.概述

1.1 JSX产生的原因

使用 createElement() 方法创建复杂 dom 结构

const ul = React.createElement('ul', null,
  React.createElement('li', null, 'Hello'),
  React.createElement('li', null, 'React'),
  React.createElement('li', null,
    React.createElement('span', null, '我是'),
    React.createElement('span', null, '初辰')
  )
)

使用 JSX 语法创建复杂 dom 结构

const ul =
  <ul>
    <li>Hello</li>
    <li>React</li>
    <li>
      <span>我是</span>
      <span>初辰</span>
    </li>
  </ul>

在这里插入图片描述

由于通过 createElement() 方法创建的 React 元素有一些问题,代码比较繁琐,结构不直观,无法一眼看出描述的结构,不优雅,用户体验不爽

1.2 JSX的概述

JSX是JavaScript XML 的简写,表示在JavaScript代码中写HTML格式的代码
优势:声明式语法更加直观,与HTML结构相同,降低了学习成本,提升开发效率

2.入门

2.1 使用步骤

使用JSX语法创建react元素

let h1 = <h1>初辰通过JSX创建的元素</h1>

使用ReactDOM来渲染元素

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

2.2 为什么在脚手架中可以使用JSX语法?

  • JSX 不是标准的ECMAScript语法,它是ECMAScript的语法拓展
  • 需要使用babel编译处理后,才能在浏览器环境中使用
  • create-react-app脚手架中已经默认有该配置,无需手动配置
  • 编译JSX语法的包: @bable/preset-react

2.3 注意点

  • React元素的属性名使用驼峰命名法
  • 特殊属性名:class -> className,for -> htmlFor,tabindex -> tabIndex
  • 如果没有子节点的React元素可以用 /> 来结束
  • 推荐:使用 小括号包裹JSX,从而避免JS中自动插入分号报错

3.JSX语法

JSX是来描述页面的结构,一般在编写业务逻辑渲染页面的时候,需要涉及到传递值,调用函数,判断条件,循环等,这一些在JSX中都能得到支持

3.1 嵌入JS表达式

语法:

{JavaScritp表达式}

例子:

let content = '插入的内容'
let h1 = <h1>初辰通过JSX创建的元素+ {content}</h1>

在这里插入图片描述

3.2 条件渲染

根据不同的条件来渲染不同的JSX结构

let isShow = false
let text = ''
if (isShow === true) {
  text = '初辰1'
} else {
  text = '初辰2'
}

在这里插入图片描述
写JSX的条件渲染与我们之前编写代码的逻辑是差不多的,根据不同的判断逻辑,返回不同的 JSX结构,然后渲染到页面中

3.3 列表渲染

  • 如果需要渲染一组数据,我们应该使用数组的 map () 方法
  • 注意:渲染列表的时候需要添加key属性,key属性的值要保证唯一
  • 原则:map()遍历谁,就给谁添加key属性
  • 注意:尽量避免使用索引号作为key
let arr = [
  {id:1,name:'三国演义'},
  {id:2,name:'水浒传'},
  {id:3,name:'西游记'},
  {id:4,name:'红楼梦'}
]
let ul = (<ul>
  {arr.map(item => <li key={item.id}>{item.name}</li>)}
 </ul>)
ReactDOM.render(ul,document.getElementById('root'))

在这里插入图片描述

3.4 样式处理

行内样式 -style
在style里面我们通过对象的方式传递数据

let ul = (<ul style={{ 'color': 'red', "backgroundColor": 'pink' }}>
  {arr.map(item => <li key={item.id}>{item.name}</li>)}

在这里插入图片描述
类名 -className
创建CSS文件 index.css 编写样式代码

.container {
  text-align: center;
  color: rgb(124, 11, 11);
  background-color: rgb(105, 105, 243);
}

在js中进行引入,然后设置类名即可

import './index.css'
let ul = (<ul className='container'>
  {arr.map(item => <li key={item.id}>{item.name}</li>)}
</ul>)

在这里插入图片描述

四、React组件

  • 组件是React的一等公民,使用React就是在用组件
  • 组件表示页面中的部分功能
  • 组合多个组件实现完整的页面功能
  • 特点:可复用、独立、可组合

1.组件的创建方式

1.1 函数创建组件

  • 函数组件:使用JS的函数创建组件
  • 约定:函数名称必须以大写字母开头,函数组件必须有返回值,表示该组件的结构,如果返回值为null,表示不渲染任何内容
    编写函数组件
function Hello () {
  return (
    <div>这是初辰的第一个函数组件</div>
  )
}

利用ReactDOM.render()进行渲染

ReactDOM.render(<Hello />, document.getElementById('root'))

在这里插入图片描述

1.2 类组件

  • 使用ES6语法的class创建的组件
  • 约定1:类名称也必须要大写字母开头
  • 约定2:类组件应该继承React.Component父类,从而可以使用父类中提供的方法或者属性
  • 约定3:类组件必须提供 render 方法
  • 约定4:render方法中必须要有return返回值
    创建class类,继承React.Component,在里面提供render方法,在return里面返回内容
class Hello extends React.Component {
  render () {
    return (
      <div>这是初辰的第一个类组件</div>
    )
  }
}

通过ReactDOM进行渲染

ReactDOM.render(<Hello />,document.getElementById('root'))

在这里插入图片描述

1.3 抽离成单独的JS文件

创建Hello.js, 在Hello.js 中导入React,创建组件,在Hello.js中导出

import React from 'react'
class fn extends React.Component {
  render () {
    return (
      <div>单独抽离出来的 Hello</div>
    )
  }
}
export default fn

在index.js中导入Hello组件,渲染到页面

import ReactDOM from 'react-dom';
import Hello from './hello'
ReactDOM.render(<Hello />, document.getElementById('root'))

在这里插入图片描述

2.React事件处理

2.1 事件绑定

  • React事件绑定语法与DOM事件语法相似
  • 语法:on+事件名称=事件处理函数,比如 onClick = function(){}
  • 注意:React事件采用驼峰命名法
class Hello extends React.Component {
  clickHandle () {
    console.log('点击了')
  }
  render () {
    return (
      <button onClick={this.clickHandle}>点我点我点我</button>
    )
  }
}

在这里插入图片描述

2.2 事件对象

  • 可以通过事件处理函数的参数获取到事件对象
  • React中的事件对象叫做:合成事件
  • 合成事件:兼容所有浏览器,无需担心跨浏览器兼容问题
  • 除兼容所有浏览器外,它还拥有和浏览器原生事件相同的接口,包括 stopPropagation()preventDefault()
  • 如果你想获取到原生事件对象,可以通过 nativeEvent 属性来进行获取
  clickHandle (e) {
    console.log(e.nativeEvent)
  }

在这里插入图片描述

2.3 支持的事件

事件事件名属性
Clipboard Events 剪切板事件onCopy onCut onPasteDOMDataTransfer clipboardData
compositionEvent 复合事件onCompositionEnd onCompositionStart onCompositionUpdatestring data
Keyboard Events 键盘事件onKeyDown onKeyPress onKeyUpnumber keyCode
Focus Events 焦点事件onFocus onBlurDOMEventTarget relatedTarget
Form Events 表单事件onChange onInput onInvalid onSubmit
Mouse Events 鼠标事件onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp
Pointer Events 指针事件onPointerDown onPointerMove onPointerUp onPointerCancel onGotPointerCapture onLostPointerCapture onPointerEnter onPointerLeave onPointerOver onPointerOut
Selection Events 选择事件onSelect
Touch Events 触摸事件onTouchCancel onTouchEnd onTouchMove onTouchStart
UI Events UI 事件onScroll
Wheel Events 滚轮事件onWheelnumber deltaMode number deltaX number deltaY number deltaZ
Media Events 媒体事件onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted onEnded onError onLoadedData onLoadedMetadata onLoadStart onPause onPlay
Image Events 图像事件onLoad onError
Animation Events 动画事件onAnimationStart onAnimationEnd onAnimationIteration

3.有状态组件和无状态组件

  • 函数组件又叫做 无状态组件,类组件又叫做 有状态组件
  • 状态(state) 即数据
  • 函数组件没有自己的状态,只负责数据展示
  • 类组件有自己的状态,负责更新UI,让页面动起来

3.1 State和SetState

state基本使用

  • 状态(state)即数据,是组件内部的私有数据,只能在组件内部使用
  • state的值是对象,表示一个组件中可以有多个数据
  • 通过this.state来获取状态
  state = {
    count: 0
  }
  render () {
    return (
      <div>计数器 :{this.state.count}</div>
    )
  }

在这里插入图片描述
setState() 修改状态

  • 语法:this.setState({要修改的数据})
  • 不要直接修改state中的值,这是错误的
  • setState() 作用:1.修改 state 2.更新UI
  • 思想:数据驱动视图
    在这里插入图片描述
addCount = () => {
    this.setState({
      count: this.state.count + 1
    })
  }
  render () {
    return (
      <div>
        <div>计数器 :{this.state.count}</div>
        <button onClick={this.addCount}>+1</button>
      </div>
    )
  }

在这里插入图片描述

  • 修改state里面的值我们需要通过 this.setState() 来进行修改
  • React底层会有监听,一旦我们调用了setState导致了数据的变化,就会重新调用一次render方法,重新渲染当前组件

4.组件的props

  • 组件时封闭的,要接受外部数据应该通过props来实现
  • props的作用:接收传递给组件的数据
  • 传递数据:给组件标签添加属性
  • 接收数据:函数组件通过 参数 props接收数据,类组件通过 this.props接收数据
class App extends React.Component {
  render () {
    return (
      <div>接收到的数据:{this.props.text}</div>
    )
  }
}
ReactDOM.render(<App text={'Hello Word'} />, document.getElementById('root'))

在这里插入图片描述特点

  • 可以给组件传递任意类型的数据
  • props是只读属性,不能对值进行修改
  • 注意:使用类组件时,如果写了构造函数,应该将props传递给super(),否则,无法在构造函数中获取到props,其他的地方是可以拿到的

5.组件通讯的三种方式

5.1 父组件传递数据给子组件

  • 父组件提供要传递的state数据
  • 给子组件标签添加属性,值为state中的数据
  • 子组件中通过props接收父组件中传递的数据
class App extends React.Component {
  render () {
    return (
      <div>接收到的数据:{this.props.text}</div>
    )
  }
}
ReactDOM.render(<App text={'Hello Word'} />, document.getElementById('root'))

5.2 子组件传递数据给父组件

  • 利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数
  • 父组件提供一个回调函数,用来接收数据
  • 将该函数作为属性的值,传递给子组件
class Fat extends React.Component {
  getSonMsg = (msg) => {
    console.log(msg);
  }
  render () {
    return (
      <Son getMsg={this.getSonMsg} />
    )
  }
}
class Son extends React.Component {
  handleClick = () => {
    this.props.getMsg('子元素的值')
  }
  render () {
    return (
      <button onClick={this.handleClick}>点我传值</button>
    )
  }
}
ReactDOM.render(<Fat />, document.getElementById('root'))

5.3 Context跨组件传递数据

如果出现层级比较多的情况下(例如:爷爷传递数据给孙子),我们会使用Context来进行传递
使用步骤
调用 React.createContext() 创建 Provider(提供数据) 和 Consumer(消费数据) 两个组件

const {Provider,Consumer} = React.createContext()

使用Provider 组件作为父节点,设置value属性,表示要传递的数据

<Provider value="李白"><Node /></Provider>

哪一层想要接收数据,就用Consumer进行包裹,在里面回调函数中的参数就是传递过来的值

<Consumer>{data => <span>子节点--{data}</span>}</Consumer>

在这里插入图片描述

6. props进阶

6.1 children属性

  • children属性: 表示组件标签的子节点,当组件标签有子节点时,props就会有该属性
  • children属性与普通的props一样,值可以使任意值(文本、react元素、组件、甚至是函数)
function Fat (props) {
  return (
    <div>组件的子节点:{props.children}</div>
  )
}
ReactDOM.render(<Fat>初辰</Fat>, document.getElementById('root'))

6.2 props校验

  • 对于组件来说,props是外来的,无法保证组件使用者传入什么格式的数据
  • 如果传入的数据不对,可能会导致报错
  • 关键问题:组件的使用者不知道需要传递什么样的数据
  • props校验:允许在创建组件的时候,指定props的类型、格式等
  • 作用:捕获使用组件时因为props导致的错误,给出明确的错误提示,增加组件的健壮性
    使用步骤
  • 安装包 prop-types (npm add props-types)
  • 导入prop-types 包
  • 使用 组件名.propTypes={} 来给组件的props添加校验规则
  • 校验规则通过PropTypes对象来指定
import PropTypes from 'prop-types'
Fat.propTypes = {
  name: PropTypes.string
}

在这里插入图片描述
在这里插入图片描述

原文链接:https://blog.csdn.net/chuenst/article/details/117223100




所属网站分类: 技术文章 > 博客

作者:西小口到了吗

链接:http://www.qianduanheidong.com/blog/article/116121/1ad9cd20f58e994164ac/

来源:前端黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

9 0
收藏该文
已收藏

评论内容:(最多支持255个字符)