1.create-react-app脚手架的应用及优化
1.create-react-app是一个命令行工具,用于快速生成基于React的单页面应用程序的脚手架。
2.全局安装第三方脚手架
npm install -g create-react-app
3.创建项目
create-react-app <project_name>
4.暴露配置文件(执行后可看到config文件夹)
npm run eject
5.启动项目(记得切换到项目目录中去)
npm start
小贴士:
安装出现request to https://registry.npm.taobao.org/webpack failed,
可以npm config set registry https://registry.npmjs.org/解决
优化:
1.npm run eject
通过命令将create-react-app配置暴露出来,然后修改webpack和babel配置
2.优化图片和字体加载
3.代码分割
2.jsx的基础知识和实战应用
概念:JSX是Javascript XML(HTML)的缩写,表示在JS代码中书写HTML结构
作用:在React中创建HTML结构(页面UI结构)
优势:
1.采用类似于HTML的语法,降低学习成本,会HTML就会JSX
2.充分利用JS自身可编程能力创建HTML结构
(JSX并不是标准的JS语法,是js的语法扩展,浏览器默认是不识别的,脚手架中内置的@babel/plugin-ttansform-react-jsx包,用来解析该语法)
JSX的注意事项:
1.JSX必须有一个根节点,如果没有根节点,可以使用<></>(幽灵节点)替代
2.所有标签必须形成闭合,成对闭合或者自闭合都可以
3.JSX的语法更加贴近JS语法,属性名采用驼峰命名法className -> htmlFor
4.JSX支持多行(换行),如果需要换行,需使用()包裹,防止Bug出现
1.JSX列表渲染:页面的构建离不开重复的列表结构,比如商品列表等,vue中用的是v-for,react是使用数组map的方法
const songs = [
{id: 1, name: '痴心绝对'},
{id: 2, name: '像我这样的人'},
{id: 3, name: '南山南'}
]
function App () {
return (
<div className="App>
<ul>
{
songs.map(item => <li>{item.name}</li> )
}
</ul>
</div>
)
}
2.JSX条件渲染:根据是否满足条件生成HTML结构,比如Loading效果,可以使用三元运算符或逻辑与(&&)运算符
const flag = true
function App () {
return (
<div className="App">
{flag ? 'react真有趣' : 'vue真有趣'}
{flag ? <span>this is span</span> : null}
</div>
)
}
3.JSX样式处理
// 1.行内样式
function App () {
return (
<div className="App">
<div style={{color: 'red'}}>this is a div</div>
</div>
)
}
// 2.行内样式-更优写法
const styleObj = {
color: red
}
function App () {
return (
<div className="App">
<div style={styleObj}>this is a div</div>
</div>
)
}
// 3.类名-className(推荐)
// app.css
.title{
font-size: 30px;
color: blue;
}
//app.js
import './app.css'
fucntion App () {
return (
<div className="App">
<div className='title'>this is a div</div>
</div>
)
}
// 4.类名-className-动态类名控制
import './app.ccs'
const showTitle = true
function App () {
return (
<div className="App">
<div className={showTitle ? 'title' : ''}>this is a div</div>
</div>
)
}
3.受控和非受控组件属性深入分析
受控组件和非受控组件是React中两种处理表单元素的方式,两者的区别如下:
受控组件:受控组件是指由React控制表单元素的值和状态的组件。在受控组件中,表单元素的值由React组件的状态(state)管理,并通过事件监听和回调函数来更新状态,每当用户输入内容或选择选项时,都会触发相应的事件处理函数,从而更新组件的状态和表单元素的值。例如,在React中,一个受控的输入框的值会通过其value属性绑定到某个状态(state),并且当用户输入时,onChange事件会被触发以更新该状态,进而重新渲染组件。受控组件适用于需要对用户输入进行验证和处理的表单,以及表单元素之间有复杂的关联关系需要根据其他输入的值动态更新的场景。
非受控组件:非受控组件则是指表单元素的值不由React状态控制的组件,其值通常由DOM自身维护。在非受控组件中,可以通过ref获取表单元素的值,并在需要时手动获取或设置其值。非受控组件适用于表单元素的值不需要进行验证或处理的场景,以及对表单元素的值进行直接访问或操作的场景。
总的来说,选择使用受控组件或非受控组件应根据实际需求进行判断。对于大部分表单场景,推荐使用受控组件以获得更好的可维护性和可控性,而在某些简单场景下,或者需要操作大量表单元素时,才考虑使用非受控组件以简化代码。
4.react合成事件和双向数据绑定
react合成事件:是react模拟的一种事件处理方式,为了解决跨浏览器的兼容性问题。当用户与DOM交互时,React会通过一个称为“合成事件”的系统来管理事件。
react合成事件如下:onChange,onClick,onDoubleClick,onMouseDown,onMouseUp,
onMouseEnter,onMouseLeave, onMouseMove,onMouseOver,onKeyUp,onKeyDown,onkeyPress,onScroll,onWheel,onCopy,onCut,onPaste,onLoad,onError
// 简单的react双向数据绑定的例子
import React, { useState } from 'react'
const InputComponent = () => {
const [value, setValue] = useState('');
// 处理输入框值的变化
const handleChange = (event) => {
setValue(event.target.value); // 更新状态
}
return {
<div>
<input type="text" value={value} onChange={handleChange}/>
<p>输入的内容是: {value}</p>
</div>
}
}
export default InputComponent;
5.函数式组件及React Hooks
react官方提供了两种定义组件的方式:
函数式组件:适用于简单组件定义
类式组件:适用于复杂组件定义
// 创建函数式组件
function Test (){
return <h1>我是测试组件</h1>
}
// 通过react进行render来进行渲染
ReactDom.render(<Test/>, document.getElementById('root1'))
react hooks:是React框架中的一个重要特性,它允许函数组件使用React的状态和其他特性,而无需编写class组件。
常用的hooks如下:
useState, useEffect, useContext, useCallback, useMemo, useRef,
useImperativeHandle, useLayoutEffect
6.类组件及生命周期函数(Component & Pure Component)
类组件:是指通过ES6类来定义的组件称为类组件,React中定义类组件有如下约定:
类组件首字母大写;
类组件必须要继承React Component父类,这个父类中的相关方法和属性都能被继承;
类组件中必须要有一个render方法;
这个render必须要有返回值,返回值的内容就是这个类组件的结构;
由于这个类组件要被别的组件引用,所以使用ES6的默认导出将其导出,便于别的组件引用
import React from 'react'
export default class Hello extends React.Component{
render () {
return (
<>
<h1>Hello组件</h1>
</>
)
}
}
// 类组件定义之后,引用这个类组件
import ReactDom from 'react-dom/client'
import Hello from './components/Hello'
const template = (
<>
<Hello></Hello>
</>
)
const root = ReactDom.createRoot(document.querySelector('#root'))
root.render(template)
React的生命周期函数:
constructor():初始化React组件的状态和方法
render():根据组件的当前状态确定页面需要渲染的内容
componentDidMount():组件挂载到Dom后调用,常用于发送网络请求或者操作DOM
componentDidUpdate():组件更新后调用,可以访问DOM
compnentWillUnmount():组件即将被卸载时调用,常用于清除定时器或者取消网络请求
7.复合组件和组件嵌套
React复合组件是指由多个简单组件形成的组件,它们通常具有良好的抽象级别和重用性。
在React中创建复合组件通常涉及以下步骤:
1.创建函数组件或类组件
2.将其他组件作为子组件嵌入其中
3.通过props传递数据和回调函数
// React复合组件示例:
import React from 'react'
import PropTypes from 'prop-types'
function Greeting({name}) {
return <h1>Hello, {name}</h1>
}
Greeting.propTypes = {
name: PropTypes.string.isRequired
}
// 复合组件
function Welcome ({name, message}) {
return (
<div>
<Greeting name={name} />
<p>{message}</p>
</div>
)
}
Welcome.propTypes = {
name: PropTypes.string.isRequired,
message: PropTypes.string.isRequired
}
export default Welcome
8.基于上下文(React.createContext)实现组件信息通信
在React中,组件间的信息通信可以通过以下几种方式实现:
1.父组件向子组件通信:通过props传递数据
2.子组件向父组件通信:通过回调函数
3.兄弟组件通信:使用共享的上下文(Context) API,或者状态管理库(如 Redux)
4.跨多个层级的组件通信:可以使用Context API 或者自定义EventEmitter