1. React概述
1.1 React是什么
- React是一个用于构建用户界面的JavaScript库。
- React的主要特点是组件化、声明式编程以及高效的DOM更新机制。
- React由Facebook开发并开源,已经成为目前最流行的前端框架之一。
1.2 React的特点
- 声明式编程:React采用声明式编程模式,使得代码更加易于阅读和理解。
- 组件化:React将页面分解成多个组件,每个组件都有自己的状态和生命周期,方便复用和维护。
- 单向数据流:React采用单向数据流的模式,父组件通过props向子组件传递数据,子组件通过回调函数向父组件传递数据。
- 虚拟DOM:React采用虚拟DOM的技术,通过对比前后两个虚拟DOM的差异,最小化页面的重绘和回流,提高页面的性能和响应速度。
- 高效:React采用高效的算法和机制,使得页面的渲染速度更快,用户体验更佳。
1.3 React的优点
- 更好的用户体验:React采用虚拟DOM,能够更快地更新页面,提升用户体验。
- 组件化开发:React采用组件化开发,使得代码更加模块化、可复用,提高开发效率。
- 代码可维护性高:React采用单向数据流,使得代码的数据流动清晰可见,方便维护和调试。
- 社区活跃:React拥有庞大的社区和生态圈,能够提供丰富的插件和组件,方便开发。
1.4 React的缺点- React的缺点:
- 学习曲线较陡峭,需要一定的JavaScript基础和了解JSX语法;
- 只关注视图层,不涉及其他方面,需要与其他库或框架配合使用;
- 代码复杂度较高,需要编写大量的组件和逻辑代码;
- 不支持IE8及以下版本的浏览器,需要使用polyfill进行兼容。
2. React基础知识
2.1 JSX语法
- JSX语法实例:
const element = <h1>Hello, world!</h1>; // JSX语法
ReactDOM.render(element, document.getElementById('root')); // 渲染到页面
- JSX表达式实例:
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = {
firstName: 'Tony',
lastName: 'Stark'
};
const element = (
<h1>
Hello, {
formatName(user)}!
</h1>
);
ReactDOM.render(element, document.getElementById('root')); // 渲染到页面
- JSX属性实例:
const element = <div tabIndex="0">Hello, world!</div>; // JSX属性
ReactDOM.render(element, document.getElementById('root')); // 渲染到页面
2.2 组件
- 2.2 组件
-
示例一:Hello World 组件
import React from 'react'; function HelloWorld() { return <h1>Hello, World!</h1>; } export default HelloWorld;
-
示例二:计数器组件
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>Count: { count}</p> <button onClick={ () => setCount(count + 1)}>Increment</button> <button onClick={ () => setCount(count - 1)}>Decrement</button> </div> ); } export default Counter;
-
示例三:表格组件
import React from 'react'; function Table(props) { const { data } = props; return ( <table> <thead> <tr> <th>Name</th> <th>Age</th> <th>Gender</th> </tr> </thead> <tbody> { data.map((item) => ( <tr key={ item.id}> <td>{ item.name}</td> <td>{ item.age}</td> <td>{ item.gender}</td> </tr> ))} </tbody> </table> ); } export default Table;
2.2.1 函数式组件
- 函数式组件
function Welcome(props) {
return <h1>Hello, {
props.name}</h1>;
}
ReactDOM.render(
<Welcome name="John" />,
document.getElementById('root')
);
2.2.2 类组件
- 类组件是React中定义组件的一种方式,使用ES6 class语法来声明组件。
- 类组件必须继承React.Component类,并实现render方法来描述组件的UI。
- 类组件可以定义自己的状态state,通过setState方法来更新状态并重新渲染组件。
- 类组件也可以定义自己的方法,用于处理用户交互或其他逻辑。
- 类组件可以接收props作为输入数据,通过this.props来访问。
- 类组件的生命周期包括挂载、更新和卸载三个阶段,可以通过重写生命周期方法来实现一些特定的逻辑。
示例:
import React, {
Component } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
handleClick = () => {
this.setState({
count: this.state.count + 1 });
}
render() {
return (
<div>
<h1>{
this.props.title}</h1>
<p>Count: {
this.state.count}</p>
<button onClick={
this.handleClick}>Click me</button>
</div>
);
}
}
export default MyComponent;
表格示例:
属性/方法 | 描述 |
---|---|
state | 组件的状态对象 |
setState() | 更新组件的状态 |
props | 组件的输入属性 |
render() | 描述组件UI的方法 |
componentDidMount() | 组件挂载后调用的方法 |
componentDidUpdate() | 组件更新后调用的方法 |
componentWillUnmount() | 组件卸载前调用的方法 |
2.3 Props和State
- Props和State的区别:
区别点 | Props | State |
---|---|---|
存放位置 | 父组件传递给子组件 | 组件内部初始化 |
是否可变 | 不可变,只读 | 可变,可修改 |
对应组件类型 | 函数组件和类组件 | 只有类组件 |
触发视图更新 | 由父组件传递的props改变 | 由组件自身调用setState()方法 |
生命周期 | 不影响组件生命周期 | 可能会触发shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate等生命周期 |
- Props的使用:
function ParentComponent() {
const name = "小明";
return (
<ChildComponent name={
name} />
);
}
function ChildComponent(props) {
return (
<div>
<p>我是子组件</p>
<p>我的名字是:{
props.name}</p>
</div>
);
}
- State的使用:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
handleClick = () => {
this.setState({
count: this.state.count + 1
});
}
render() {
return (
<div>
<p>当前计数:{
this.state.count}</p>
<button onClick={
this.handleClick}>增加计数</button>
</div>
);
}
}
2.4 生命周期
- React组件的生命周期包括:挂载阶段、更新阶段、卸载阶段。
- 挂载阶段包括constructor、getDerivedStateFromProps、render、componentDidMount。
- 更新阶段包括getDerivedStateFromProps、shouldComponentUpdate、render、getSnapshotBeforeUpdate、componentDidUpdate。
- 卸载阶段包括componentWillUnmount。
2.5 事件处理- React中的事件处理与原生DOM事件处理有所不同,它使用了合成事件(SyntheticEvent)来封装浏览器的原生事件,提供了跨浏览器的一致性。
- 在React中,事件处理函数需要绑定到组件实例上,可以使用箭头函数或在构造函数中使用bind方法来绑定。
- 事件处理函数中的this默认指向组件实例,而不是触发事件的DOM元素。
- 事件处理函数的参数e是一个合成事件对象,它包含了与原生事件相同的属性和方法,如e.target, e.stopPropagation()等。
- React中的事件处理函数不能返回false来阻止事件冒泡,而需要使用e.stopPropagation()或e.preventDefault()来达到相同的效果。
- 示例代码:
class MyComponent extends React.Component {
handleClick = (e) => {
console.log('Button clicked!');
}
render() {
return (
<button onClick={
this.handleClick}>Click me</button>
);
}
}
表格语法示例:
React事件处理 | 说明 |
---|---|
onClick | 鼠标点击事件 |
onDoubleClick | 鼠标双击事件 |
onMouseDown | 鼠标按下事件 |
onMouseUp | 鼠标松开事件 |
onKeyDown | 键盘按下事件 |
onKeyUp | 键盘松开事件 |
onFocus | 元素获得焦点事件 |
onBlur | 元素失去焦点事件 |
3. React进阶知识
3.1 高阶组件
- 高阶组件是什么?
- 高阶组件是一个函数,它接收一个组件作为参数并返回一个新的组件。
- 高阶组件的作用是什么?
- 高阶组件可以帮助我们实现组件的复用,逻辑的抽象和封装,以及在不改变原组件的情况下增强组件的功能等。
- 高阶组件的实现方式有哪些?
- 属性代理:通过包裹原组件并向其传递新的props来增强组件的功能。
- 反向继承:通过继承原组件并重写其方法来增强组件的功能。
- 高阶组件的应用场景有哪些?
- 条件渲染:根据条件渲染不同的组件。
- 认证与授权:根据用户的认证状态和权限渲染不同的组件。
- 数据获取与处理:将数据获取和处理的逻辑从组件中抽离出来,使组件更加简洁和可复用。
- 功能增强:增强组件的功能,如添加日志记录、性能统计等。
- 高阶组件的注意事项有哪些?
- 高阶组件不应该修改原组件的props和state。
- 高阶组件应该透传原组件的props和context。
- 高阶组件应该遵循函数式编程的原则,不应该有副作用。
3.2 Hooks
- useState
import React, {
useState } from 'react';
function Example() {
// 声明一个叫 "count" 的 state 变量
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {
count} times</p>
<button onClick={
() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
- useEffect
import React, {
useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// 相当于 componentDidMount 和 componentDidUpdate:
useEffect(() => {
// 使用浏览器的 API 更新页面标题
document.title = `You clicked ${
count} times`;
});
return (
<div>
<p>You clicked {
count} times</p>
<button onClick={
() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
- useContext
import React, { useContext } from 'react'; const ThemeContext = React.createContext('light'); function App() { return ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); } function Toolbar(props) { return ( <div> <ThemedButton /> </div> ); } function ThemedButton() { const theme = useContext(ThemeContext); return <button>{ theme}</button>; }
- useReducer
import React, {
useReducer } from 'react';
const initialState = {
count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {
count: state.count + 1 };
case 'decrement':
return {
count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {
state.count}
<button onClick={
() => dispatch({
type: 'increment' })}>+</button>
<button onClick={
() => dispatch({
type: 'decrement' })}>-</button>
</>
);
}
- useCallback
import React, { useState, useCallback } from 'react'; function Example() { const [count, setCount] = useState(0); const [text, setText] = useState(''); const handleChange = useCallback(e => { setText(e.target.value); }, []); return ( <div> <p>You clicked { count} times</p> <button onClick={ () => setCount(count + 1)}> Click me </button> <input value={ text} onChange={ handleChange} /> </div> ); }
- useMemo
import React, {
useState, useMemo } from 'react';
function Example() {
const [count, setCount] = useState(0);
const expensiveCount = useMemo(() => {
return count ** 2;
}, [count]);
return (
<div>
<p>You clicked {
count} times</p>
<p>Expensive count: {
expensiveCount}</p>
<button onClick={
() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
3.2.1 useState
- useState基础用法:
import React, {
useState } from 'react';
function Example() {
// 声明一个叫 "count" 的 state 变量
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {
count} times</p>
<button onClick={
() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
- useState使用函数更新状态:
import React, {
useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(prevCount => prevCount + 1);
}
return (
<div>
<p>You clicked {
count} times</p>
<button onClick={
handleClick}>
Click me
</button>
</div>
);
}
-
useState可以接受函数作为初始值:
import React, { useState } from 'react'; function Example() { const [count, setCount] = useState(() => { const initialCount = 0; return initialCount; }); return ( <div> <p>You clicked { count} times</p> <button onClick={ () => setCount(count + 1)}> Click me </button> </div> ); }
-
useState可以使用解构赋值:
import React, { useState } from 'react'; function Example() { const [state, setState] = useState({ count: 0, name: '张三' }); function handleClick() { setState(prevState => { return { ...prevState, count: prevState.count + 1 }; }); } return ( <div> <p>{ state.name} clicked { state.count} times</p> <button onClick={ handleClick}> Click me </button> </div> ); }
3.2.2 useEffect
-
useEffect是React中的一个Hook,用于处理组件中的副作用操作,比如数据获取、DOM操作等。
扫描二维码关注公众号,回复: 16338974 查看本文章 -
useEffect的基本用法如下:
import React, { useEffect } from 'react'; function Example() { useEffect(() => { // 在这里处理副作用操作 return () => { // 在组件卸载时执行清除操作 }; }, [/* 依赖项 */]); return <div>Example</div>; }
-
useEffect接收两个参数,第一个参数是一个回调函数,用于处理副作用操作;第二个参数是一个数组,用于指定副作用操作的依赖项,只有依赖项发生变化时,才会重新执行副作用操作。
-
useEffect还可以返回一个清除函数,用于在组件卸载时执行清除操作。
3.2.3 useContext
- 使用useContext进行组件间通信
import React, {
useContext } from 'react';
// 创建一个context
const MyContext = React.createContext();
// 在父组件中设置context的值
function Parent() {
return (
<MyContext.Provider value="hello">
<Child />
</MyContext.Provider>
);
}
// 在子组件中使用context的值
function Child() {
const value = useContext(MyContext);
return <div>{
value}</div>;
}
3.3 Redux
- Redux是一种状态管理工具,它可以帮助我们更好地管理React中的数据流。
- Redux有三个核心概念:store、action和reducer。
- store是Redux中保存数据的地方,我们可以通过store.getState()来获取store中的数据。
- action是Redux中描述事件的对象,它必须包含一个type属性,用来描述事件的类型。
- reducer是Redux中处理事件的函数,它接收当前的state和action,返回一个新的state。
- Redux的使用需要安装redux和react-redux两个包,并且需要在应用中创建一个store。
- 使用Redux时,我们需要定义action和reducer,并将它们注册到store中。
- 可以使用redux-devtools来方便地调试Redux应用。
- Redux还可以与React结合使用,通过react-redux提供的connect函数将Redux的状态映射到React组件的props中。
- 在使用Redux时,需要注意不要滥用Redux,只有在需要管理大量共享状态时才使用它,否则会导致代码变得复杂难以维护。
3.4 React Router- React Router是什么?
- React Router是一个基于React之上的强大路由库,它可以让你向应用中加入路由功能,以便用户可以通过URL访问不同的页面。
- React Router的使用方法
- 安装React Router:
npm install react-router-dom
- 在应用中引入React Router:
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
- 使用
<Router>
组件包裹整个应用,使用<Route>
组件定义路由规则,使用<Link>
组件生成链接。
- 安装React Router:
- React Router的常用API
<Route>
组件:定义路由规则,包含path
和component
两个属性。<Link>
组件:生成链接,包含to
属性。useHistory
Hook:获取路由历史记录,可以用来实现页面跳转。
- React Router的高级用法
- 嵌套路由:在一个路由规则中嵌套另一个路由规则。
- 动态路由:使用参数来定义路由规则,例如
/users/:id
。 - 路由守卫:在路由跳转前进行权限验证或其他操作。可以使用
<Route>
组件的render
属性或者自定义组件来实现。
4. React实战
4.1 创建React应用
- 使用create-react-app创建React应用
- 在应用中添加组件并渲染
- 使用props传递数据给组件
- 使用state管理组件内部状态
- 处理组件事件
- 使用生命周期方法控制组件行为
- 使用React Router实现页面路由
- 使用Redux管理应用状态
- 使用React Hooks优化组件代码
- 使用React测试工具进行单元测试
- 使用React Native开发移动应用
- 使用Next.js实现服务器渲染
- 使用React与其他技术栈进行集成,如GraphQL、TypeScript等
- 使用React开发实际项目的经验分享
- 总结与展望
表格语法:
序号 | 内容 |
---|---|
1 | 使用create-react-app创建React应用 |
2 | 在应用中添加组件并渲染 |
3 | 使用props传递数据给组件 |
4 | 使用state管理组件内部状态 |
5 | 处理组件事件 |
6 | 使用生命周期方法控制组件行为 |
7 | 使用React Router实现页面路由 |
8 | 使用Redux管理应用状态 |
9 | 使用React Hooks优化组件代码 |
10 | 使用React测试工具进行单元测试 |
11 | 使用React Native开发移动应用 |
12 | 使用Next.js实现服务器渲染 |
13 | 使用React与其他技术栈进行集成,如GraphQL、TypeScript等 |
14 | 使用React开发实际项目的经验分享 |
15 | 总结与展望 |
4.2 React与其他框架集成
-
React与Vue.js集成
示例代码:
// 在Vue.js组件中使用React组件 <template> <div> <my-react-component :prop1="value1" @event1="handleEvent"></my-react-component> </div> </template> <script> import MyReactComponent from './MyReactComponent'; export default { components: { 'my-react-component': MyReactComponent }, data() { return { value1: 'some value' } }, methods: { handleEvent() { // 处理React组件触发的事件 } } } </script>
-
React与Angular集成
示例代码:
// 在Angular组件中使用React组件 import { Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { MyReactComponent } from './MyReactComponent'; @Component({ selector: 'app-my-angular-component', template: '<div #reactContainer></div>', }) export class MyAngularComponent implements OnInit { @ViewChild('reactContainer', { static: true }) reactContainer: ElementRef; @Input() prop1: string; ngOnInit() { ReactDOM.render(<MyReactComponent prop1={ this.prop1} />, this.reactContainer.nativeElement); } }
-
React与jQuery集成
示例代码:
// 在jQuery插件中使用React组件 (function($) { $.fn.myJqueryPlugin = function(options) { const settings = $.extend({ }, options); return this.each(function() { const $this = $(this); const props = { prop1: settings.prop1 }; ReactDOM.render(<MyReactComponent { ...props} />, $this[0]); }); }; })(jQuery);
4.3 React性能优化
4.4 React测试- 使用Jest和Enzyme进行组件测试
- 使用React Testing Library进行组件测试
- 使用Cypress进行端到端测试
- 使用Sinon进行单元测试
- 使用Mocha和Chai进行集成测试
- 使用Jasmine进行全栈测试
- 表格:
测试框架 | 优点 | 缺点 |
---|---|---|
Jest | 快速、易用、支持快照测试 | 集成度高,不易定制 |
Enzyme | 支持浅渲染和深渲染,易于测试组件生命周期 | 不支持React16的新特性 |
React Testing Library | 与用户行为更贴合,测试更真实 | 不易测试组件内部状态 |
Cypress | 可以进行端到端测试,支持调试 | 无法测试多个浏览器 |
Sinon | 可以模拟函数和对象,易于测试异步代码 | 需要与其他测试框架一起使用 |
Mocha和Chai | 灵活、易用,可以与其他测试框架集成 | 需要手动安装和配置 |
Jasmine | 可以进行全栈测试,易于测试异步代码 | 集成度不高,不易定制 |
5. 参考资料
5.1 React官方文档
-
React官方文档:https://reactjs.org/docs/getting-started.html
React官方文档是React框架的官方文档,提供了详细的React介绍、快速上手指南、组件API等内容,是学习React的必备资料。在这里,你可以了解到React的基本概念、核心特性、组件生命周期、事件处理等知识点,并且可以通过实例代码进行实践操作,加深对React的理解。同时,React官方文档也提供了React Native、React VR等相关技术的文档,方便开发者进行深入学习和应用。
5.2 React源码解析
- React源码解析官方文档:https://reactjs.org/docs/codebase-overview.html
- React源码解析系列博客:https://react.iamkasong.com/
- React源码解析视频教程:https://www.bilibili.com/video/BV1qE411b7cZ
- React源码解析Github仓库:https://github.com/facebook/react
- 表格:React源码解析书籍推荐
书名 | 作者 | 出版社 | 链接 |
---|---|---|---|
《React源码解析》 | 陈屹著 | 机械工业出版社 | https://book.douban.com/subject/30374649/ |
5.3 React实战教程- React官方文档:https://reactjs.org/docs/getting-started.html
- React中文文档:https://zh-hans.reactjs.org/
- 5.3 React实战教程:
- React小书:http://huziketang.mangojuice.top/books/react/
- React Native官方文档:https://reactnative.dev/docs/getting-started
- React Router官方文档:https://reactrouter.com/web/guides/quick-start
- Ant Design官方文档:https://ant.design/docs/react/introduce-cn
- Material-UI官方文档:https://material-ui.com/zh/getting-started/installation/
- Redux官方文档:https://redux.js.org/introduction/getting-started
- Mobx官方文档:https://mobx.js.org/README.html
- TypeScript官方文档:https://www.tslang.cn/docs/home.html
- Next.js官方文档:https://nextjs.org/docs/getting-started
- Gatsby官方文档:https://www.gatsbyjs.com/docs/