React入门:手把手教你如何组件化
前言
在现代Web开发领域,React作为一款强大的JavaScript库,通过其组件化的开发方式彻底改变了我们构建用户界面的方式。特别是对于大型团队而言,组件化不仅提高了代码的可维护性,还极大地促进了团队成员之间的协作。
正文
话不多说,我们直接进入React写轮眼的世界
放错了,是这个
创建项目
来到vscode,我们选择vite构建工具
命令行输入npm init vite
而官方的脚手架为create-react-app
我们为什么使用vite脚手架,其实两边各有优点
- create-react-app:作为React官方提供的脚手架工具,create-react-app为开发者提供了一个零配置的起点,专注于编写应用而非配置环境。它预设了最佳实践,如Babel转换、Webpack打包等,非常适合快速原型设计和小型到中型项目的启动。
- npm init vite: Vite是一个新兴的前端构建工具,以其超快的热更新速度和原生ES模块支持而著称。使用
npm init vite
并选择React模板可以快速初始化一个基于Vite的React项目,适合追求极致开发体验和性能优化的团队。
接着我们输入项目名称,依次选择
再将这三串命令输入到命令行中
便能完成项目的依赖安装和本地运行
组件
React等框架的好处正是因为这些框架都能够组件化开发
而React项目内的文件便是例子
项目结构与基础
- index.html:作为应用的入口页面,通常包含一个唯一的挂载点(如
<div id="root"></div>
),React应用将在这个点上渲染整个组件树。 - src/main.jsx:作为单点入口,使用
type="module"
指示浏览器使用ES模块进行加载。在此文件中,通过ReactDOM的render
方法将根组件挂载到页面的指定元素上。
我们直接到本地运行的网页上去看
我们在index
上只能看到root
根节点,正是因为React的组件化管理
createroot的使用
createRoot
是React 18中引入的一个新API,它位于react-dom/client
模块中,用于替代旧版中的ReactDOM.render()
方法。这个API是React Concurrent Mode(并发模式)的一部分,旨在提高React应用程序的性能和用户体验,尤其是在复杂的UI更新和动画效果处理方面。
在React 18之前,我们通常使用ReactDOM.render()
来将React组件渲染到DOM中。然而,这种方法存在一些限制,例如在执行大量UI更新时可能会阻塞浏览器的主线程,导致用户界面卡顿。为了解决这些问题,React 18引入了新的渲染机制,允许异步渲染和组件的分批更新,从而提高应用程序的响应性和性能。
createRoot
的基本用法
使用createRoot
的基本步骤如下:
-
引入
createRoot
API:import { createRoot } from 'react-dom/client';
-
创建一个root实例:
const root = createRoot(document.getElementById('root'));
-
使用
root.render()
方法来渲染React组件:root.render(<App />);
这里的<App />
是你的React组件树的根组件。
我们到main.jsx 构建我们的页面
import ReactDOM from "react-dom/client";
import React from "react";
import App from "./App";
// 接管 以root 节点
const root = ReactDOM.createRoot(
document.getElementById('root')
);
root.render(<App />);
接着我们到App.jsx
中编写我们的根组件
import AppHeader from './components/app-header';
const App = () => {
// App 的数据
const name = 'Hello World'
return(
<div className="container">
{/* 参数传递给子组件 */}
<AppHeader name = {name} theme= "day"/>
</div>
)
}
export default App
首先,我们从./components/app-header
路径导入了AppHeader
组件。这通常意味着AppHeader
组件定义在components
目录下的app-header.js
这里定义了App
组件,它是一个箭头函数组件。组件内部,我们声明了一个常量name
,其值被设定为字符串'Hello World'
。然后,在return
语句中,我们返回了一个JSX结构,该结构描述了组件的外观和行为。
在JSX结构中,<div className="container">
定义了一个带有类名container
的div
元素,这通常用于应用的布局或者应用样式。紧接着,我们看到了<AppHeader name={name} theme="day"/>
,这是AppHeader
组件的使用实例。通过name
和theme
属性,我们向AppHeader
组件传递了数据。name
属性接收了App
组件内部定义的name
变量的值,而theme
属性被硬编码为字符串"day"
。
然后我们来到app-header.jsx
写组件
const AppHeader = (props) => {
const { name } = props
const { theme }= props
return (
<div className="app-header">
<h1 className="title">{name}{theme}</h1>
</div>
)
}
export default AppHeader
这里定义了一个名为AppHeader
的函数组件,它接受一个参数props
。在React中,props
是一个特殊的对象,用于将父组件传递下来的数据和行为传递给子组件。
在这两行中,我们使用解构赋值从props
对象中提取name
和theme
属性。这使得我们可以更简洁地访问这两个属性,而不是每次都写props.name
和props.theme
。
在return
语句中,我们返回了一个JSX结构,它描述了AppHeader
组件的外观。这里我们创建了一个带有类名app-header
的div
元素,里面包含了一个带有类名title
的h1
元素。h1
元素的文本内容由name
和theme
属性拼接而成。注意,直接将两个属性值拼接在一起可能并不是最佳实践,因为theme
通常用于CSS样式而不是内容,这里只是为了演示属性的使用。
这样我们组件之间的传参就完成了
类组件
了解了react的组件化思想,还有一点我们需要掌握——组件类
在React中,类组件是一种定义组件的方式,它使用ES6的类语法。类组件相较于函数组件提供了更多的功能和灵活性,尤其是对于那些需要维护内部状态(state)和使用生命周期方法的复杂组件来说。
类组件定义遵循ES6的类语法,通常包含一个render()
方法,用于返回组件的JSX表示。类组件可以拥有内部状态,这对于存储和管理组件的动态数据非常有用。状态通过在类组件中定义一个this.state
对象来初始化。
我们来表示一下我们的心情
import { Component } from "react";
class AppBody extends Component {
constructor(props) {
super(props)
this.state = {
emoji: '😀'
}
// setInterval(()=>this.changeEmoji() ,3000)
}
componentDidMount() {
setInterval(()=>this.changeEmoji() ,3000)
}
changeEmoji() {
// Component 内置方法setState
this.setState({
emoji:this.state.emoji === '😀' ? '😂' : '😀'
})
}
render() {
const {name} = this.props
const {emoji} = this.state
return (
<div className="app-header">
<h1 className="title">心情</h1>
<div>{name}</div>
<div>{emoji}</div>
</div>
)
}
}
export default AppBody
我们先导入React库中的Component
基类,用于创建自定义的React组件。
定义一个名为AppBody
的类组件,它继承自Component
基类。
import { Component } from "react";
class AppBody extends Component {
这就是react语法糖,能够让别的语言的程序员能够看得懂此代码,实际上也只是向这个函数的 原型prototype添加属性
接着我们super(props)
调用父类Component
构造函数,它负责初始化父类Component
的一些属性和方法,一旦调用此函数,,你就可以在你的组件中通过this.props
访问所有传递给该组件的属性。
其中props
是父类传给该组件的属性,多用于初始化,外部不应修改,而state
是组件内自身属性,外界可以访问并修改,所以这里我们传入一个属性emoji
constructor(props) {
super(props);
this.state = { emoji: '😀' };
}
然后我们使用生命周期方法,在组件被渲染到DOM中之后调用。在这个方法中,我们设置了一个定时器,每3秒调用一次changeEmoji
方法,那么这个表情就会每3s改变一次。
componentDidMount() {
setInterval(()=>this.changeEmoji() ,3000)
}
再然后我们写changeEmoji()
方法,因为这个emoji
是该组件类的一个属性,所以我们需要用到setState()
来修改该属性
changeEmoji() { this.setState({ emoji: this.state.emoji === '😀' ? '😂' : '😀' }); }
最后我们通过解构获取到传入的name
的值,和本类定义的emoji
的值,然后加载到父组件内
render() {
const {name} = this.props
const {emoji} = this.state
return (
<div className="app-header">
<h1 className="title">title</h1>
<div>{emoji}</div>
<div>{name}</div>
</div>
)
}
这样我们就获得了过三秒就变脸的emoji
完整代码
import { Component } from "react";
// 类组件
// es6 Component基类
class AppBody extends Component {
constructor(props) {
super(props)
this.state = {
emoji: '😀'
}
// setInterval(()=>this.changeEmoji() ,3000)
}
componentDidMount() {
setInterval(()=>this.changeEmoji() ,3000)
}
changeEmoji() {
this.setState({
emoji:this.state.emoji === '😀' ? '😂' : '😀'
})
}
render() {
const {name} = this.props
const {emoji} = this.state
return (
<div className="app-header">
<h1 className="title">心情</h1>
<div>{name}</div>
<div>{emoji}</div>
</div>
)
}
}
export default AppBody
React中的类组件提供了一种强大的方式来创建具有复杂逻辑和动态数据的组件。它们通过状态管理和生命周期方法提供了更高级的功能,适用于需要更精细控制的应用场景。
总结
React组件化结合ES6的模块化和面向对象特性,为现代Web开发提供了一套高效、灵活的解决方案。Vite的加入进一步加速了开发流程,使得React项目能够快速启动并迭代。通过深入理解React组件的生命周期和状态管理机制,开发者可以构建出既高性能又易于维护的Web应用,为用户提供卓越的交互体验。在大型团队协作场景下,这些技术的结合更是展现了其无与伦比的优势,推动着Web开发向着更加专业和高效的方向发展。
求点赞评论收藏,有问题随时私信博主!
转载自:https://juejin.cn/post/7387353297692196874