React学习笔记
一、React 简介
React 是一个由 Facebook 开发并开源的用于构建用户界面的 JavaScript 库。它凭借组件化的开发方式,能够高效地更新和渲染页面,让开发者可以轻松创建出交互性强、动态且复杂的前端应用程序,在当今的前端开发领域应用极为广泛,众多大型项目都选择了 React 技术栈。
二、环境搭建
- 创建项目(使用 Create React App):
这是新手入门最常用、最便捷的创建 React 项目的方式。前提是你已经安装了 Node.js 和 npm(Node.js 自带 npm),然后在命令行中执行以下命令:
npx create-react-app my-app
cd my-app
npm start
执行 npm start
后,项目会在本地开发服务器启动,默认访问地址是 http://localhost:3000
,此时你就能看到初始的 React 应用界面了。
注意事项:如果后续你想要对项目的构建配置(比如 webpack 配置等)进行更深入的定制,可以执行 npm run eject
命令,不过要谨慎使用,因为这是一个不可逆的操作,执行后将无法恢复到默认的配置状态。
- 引入 React 到已有项目(通过 CDN 等方式):
你也可以在 HTML 文件中通过 CDN 引入 React 和 ReactDOM(用于将 React 组件渲染到页面上),示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React App</title>
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="your-app.js"></script>
</body>
</html>
之后在 your-app.js
中编写 React 相关代码进行开发。不过需要注意的是,通过 CDN 引入这种方式更适合简单的演示项目或者快速验证想法的场景,对于大型的实际生产项目,通常还是采用如 npm
等包管理工具安装依赖并构建的方式,这样便于管理依赖版本、进行代码打包优化等操作。
三、React 组件
- 函数组件:
这是目前 React 官方推荐使用的一种组件定义方式,它本质上就是一个普通的 JavaScript 函数,接收props
(属性)作为参数,返回要渲染的 JSX 内容。例如:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
在这个示例中,定义了 Welcome
函数组件,它接收 props
里的 name
属性,然后在返回的 JSX(一种类似 HTML 语法扩展的 JavaScript 语法,能方便地描述 UI 结构)中展示对应的欢迎语。
- 类组件(虽然使用频率相对降低,但仍需了解):
通过继承React.Component
类来定义,需要实现render
方法来返回要渲染的内容。例如:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
类组件有自己的生命周期方法,比如 componentDidMount
(在组件挂载到 DOM 后执行,常用于发起网络请求获取初始数据等操作,因为此时 DOM 已经存在,可以安全地操作 DOM 元素了)、componentWillUnmount
(在组件即将被卸载时执行,常用于清理一些在组件挂载或者更新阶段添加的资源,比如移除定时器、取消事件监听器等,防止内存泄漏)等,可以在这些方法里做一些特定的操作,像发起网络请求、添加或移除事件监听器等。
四、JSX 语法
- 基本规则:
JSX 看起来像 HTML,但实际上是 JavaScript 的一种语法扩展。在 JSX 中可以直接使用 JavaScript 表达式,通过{}
包裹,比如:
const name = "Alice";
const element = <h1>Hello, {name}</h1>;
同时,标签必须闭合,像自闭合标签 <img src="image.jpg" />
,而且自定义组件的首字母一般要大写,这样 React 才能区分是自定义组件还是普通的 HTML 元素。
- 条件渲染:
可以使用 JavaScript 的条件语句(如if-else
、三元表达式等)来根据不同条件渲染不同的内容。例如用三元表达式:
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
return (
<div>
{isLoggedIn? <UserGreeting /> : <GuestGreeting />}
</div>
);
}
- 列表渲染:
当需要渲染一组数据列表时,通常会结合map
函数来遍历数组生成对应的元素列表,要记得给每个元素添加key
属性,方便 React 进行高效的更新和识别。key
属性的值应该在列表中具有唯一性,一般可以使用数据的id
等唯一标识来作为key
。例如:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>{number}</li>
);
return <ul>{listItems}</ul>;
五、Props(属性传递)
- 传递数据:
从父组件向子组件传递数据就是通过props
。例如父组件:
function ParentComponent() {
return <ChildComponent name="Bob" age={25} />;
}
子组件就能通过 props
获取这些属性:
function ChildComponent(props) {
return (
<div>
<p>Name: {props.name}</p>
<p>Age: {props.age}</p>
</div>
);
}
- 单向数据流:
在 React 中,props
是单向传递的,即父组件传递给子组件的数据,子组件不能直接修改父组件的props
,这样有助于保持数据的可预测性和组件的独立性。如果子组件需要根据父组件传来的数据进行修改并反馈给父组件,通常需要通过父组件传递回调函数作为props
给子组件,子组件调用该回调函数来间接影响父组件的数据。
六、State(状态管理)
- 函数组件中的 State(使用
useState
Hook):useState
是 React 提供的一个 Hook,用于在函数组件中添加状态。例如:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
这里通过 useState
定义了 count
状态,并提供了 setCount
函数来更新状态,每次点击按钮就会触发 setCount
,从而更新页面上显示的计数。需要注意的是,setCount
函数更新状态是异步的,如果下一次更新依赖于当前状态的值,建议传递一个回调函数给 setCount
,像这样:setCount(prevCount => prevCount + 1)
,这样能确保获取到的是最新的状态值,避免出现意外的结果。
- 类组件中的 State:
在类组件里通过this.state
来定义和访问状态,通过this.setState
方法来更新状态,例如:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
handleClick = () => {
this.setState((prevState) => ({
count: prevState.count + 1
}));
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={this.handleClick}>
Click me
</button>
</div>
);
}
}
在使用 this.setState
时,如果更新状态依赖于当前状态,同样建议传入回调函数的形式来更新,以保证状态更新的正确性和可预测性。
七、事件处理
- 绑定事件:
在 React 中,采用驼峰命名法来绑定事件,比如onClick
、onChange
等。对于函数组件,直接在 JSX 中传入事件处理函数即可,像上面Counter
函数组件里的按钮点击事件绑定。对于类组件,可以在构造函数中绑定或者使用箭头函数的方式来绑定,例如:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log("Button clicked");
}
render() {
return <button onClick={this.handleClick}>Click me</button>;
}
}
另外,也可以直接使用箭头函数在 JSX 中绑定事件,不过这种方式在每次渲染组件时都会创建一个新的函数实例,可能会影响性能,如果组件频繁重新渲染,建议在构造函数中绑定或者采用类的实例方法绑定的形式。
- 事件对象:
事件处理函数接收的事件对象和原生 JavaScript 的事件对象有一些不同,不过包含了常用的属性和方法,比如e.preventDefault()
用于阻止默认行为(比如表单提交时阻止页面刷新等),e.target
可以获取触发事件的 DOM 元素等。同时,React 对一些事件进行了合成,使其在不同浏览器下的表现更加一致,开发者使用起来更加方便。
八、React 生命周期(主要针对类组件,函数组件通过 useEffect 等 Hook 实现类似功能)
- 挂载阶段:
constructor
:用于初始化组件的状态和绑定事件处理函数等。需要注意的是,在构造函数中调用super(props)
时,要确保传入props
参数,这样才能在构造函数中正确访问props
。componentWillMount
(已废弃,了解即可):在组件即将挂载到 DOM 之前执行,不过现在不推荐使用了,有替代的方式通过useEffect
等在函数组件里实现相关功能。例如,在函数组件中可以使用useEffect
并传入空数组作为依赖项,来模拟类组件componentDidMount
的行为,在组件首次渲染完成后执行一些操作。componentDidMount
:组件挂载到 DOM 后执行,通常在这里发起网络请求获取初始数据等操作,因为此时 DOM 已经存在,可以安全地操作 DOM 元素了。例如:
class DataFetchingComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
data: []
};
}
componentDidMount() {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(json => this.setState({ data: json }))
.catch(error => console.log(error));
}
render() {
return (
<div>
{this.state.data.map(item => <p key={item.id}>{item.name}</p>)}
</div>
);
}
}
- 更新阶段:
shouldComponentUpdate
(可以用于性能优化,可选实现):这个方法决定组件是否需要重新渲染,根据组件接收到的新props
和state
来判断,如果返回false
,组件就不会重新渲染,返回true
则会继续后续的更新流程。例如,如果一个组件的某些属性变化后并不影响其显示内容,就可以在这个方法里进行判断,避免不必要的重新渲染,提高性能。componentWillUpdate
(已废弃):在组件即将更新之前执行,同样现在有更好的替代方案了,在函数组件中可以通过useEffect
的依赖项变化来感知组件的更新情况,并做相应处理。componentDidUpdate
:组件更新后执行,可以在这里做一些基于更新后状态的操作,比如操作 DOM 或者根据新数据再次发起部分请求等,但要注意避免无限循环更新,需要合理判断条件。例如:
class UpdatedComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidUpdate(prevProps, prevState) {
if (prevState.count!== this.state.count) {
// 根据更新后的 count 状态做一些操作,比如更新 DOM 样式等
console.log(`Count has changed from ${prevState.count} to ${this.state.count}`);
}
}
handleClick = () => {
this.setState((prevState) => ({
count: prevState.count + 1
}));
}
render() {
return (
<div>
<p>Current count: {this.state.count}</p>
<button onClick={this.handleClick}>Increment</button>
</div>
);
}
}
- 卸载阶段:
componentWillUnmount
:在组件即将被卸载时执行,常用于清理一些在组件挂载或者更新阶段添加的资源,比如移除定时器、取消事件监听器等,防止内存泄漏。例如:
class TimerComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
seconds: 0
};
this.timer = null;
}
componentDidMount() {
this.timer = setInterval(() => {
this.setState((prevState) => ({
seconds: prevState.seconds + 1
}));
}, 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
}
render() {
return (
<div>
<p>Seconds passed: {this.state.seconds}</p>
</div>
);
}
}
九、React 路由(常用的有 React Router)
- 安装与基本配置:
先安装react-router-dom
(针对浏览器应用的 React 路由库):
npm install react-router-dom
然后在项目中进行基本配置,例如:
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
function Home() {
return <h2>Home Page</h2>;
}
function About() {
return <h2>About Page</h2>;
}
function App() {
return (
<Router>
<div>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</div>
</Router>
);
}
export default App;
这里定义了基本的路由结构,有首页 Home
和关于页面 About
,通过 <Link>
组件实现页面之间的导航,<Route>
组件用来匹配不同的路径并渲染对应的组件。同时,<Routes>
组件会自动匹配路径,相比旧版本的 React Router 中的 <Switch>
组件,它在处理路由匹配时更加智能和灵活,不会出现多个路由都匹配的情况(除非你有嵌套路由等特殊需求故意这样设置)。
- 动态路由参数:
可以定义带有参数的路由,例如:
function UserProfile({ match }) {
return <h2>User Profile: {match.params.userId}</h2>;
}
function App() {
return (
<Router>
<div>
<Routes>
<Route path="/user/:userId" element={<UserProfile />} />
</Routes>
</div>
</Router>
);
}
这样访问 /user/123
这样的路径时,就能在 UserProfile
组件里获取到 userId
参数并展示相关内容了。此外,还可以通过 <Route>
组件的 useParams
Hook(在函数组件中)或者 this.props.match.params
(在类组件中)来获取路由参数,方便根据不同的参数值展示不同的页面内容或者进行相应的数据获取等操作。
十、React 与后端交互(常用的是通过网络请求获取数据)
- 使用
fetch
API(原生方式):
例如在组件中发起获取数据的请求:
function DataFetchingComponent() {
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(json => setData(json))
.catch(error => console.log(error));
}, []);
return (
<div>
{data.map(item => <p key={item.id}>{item.name}</p>)}
</div>
);
}
这里使用 useEffect
Hook 在组件挂载后发起 fetch
请求,获取到数据后更新组件的状态,进而渲染出对应的内容。不过,fetch
API 有一些特点需要注意,比如它默认不会携带 cookies
,如果需要携带,要在 fetch
配置中添加 credentials: 'include'
选项;而且它返回的 Promise
在遇到网络错误时不会 reject
,只有在出现比如 404
、500
等 HTTP 状态码相关的错误时才会进入 catch
块,所以有时候需要额外判断响应的 ok
属性(response.ok
为 true
表示请求成功)来更精准地处理错误情况。
- 使用第三方库(如
axios
):
先安装axios
:
npm install axios
然后使用它发起请求,相对 fetch
来说,axios
有更方便的配置和错误处理等优点,例如:
import axios from 'axios';
function DataFetchingComponent() {
const [data, setData] = useState([]);
useEffect(() => {
axios.get('https://api.example.com/data')
.then(response => setData(response.data))
.catch(error => console.log(error));
}, []);
return (
<div>
{data.map(item => <p key={item.id}>{item.name}</p>)}
</div>
);
}
axios
可以方便地设置请求头、处理请求和响应拦截等。比如设置全局请求头:
axios.defaults.headers.common['Authorization'] = 'Bearer your_token';
还能添加请求拦截器,在每个请求发送前做一些统一处理,像添加加载动画显示等:
axios.interceptors.request.use(config => {
// 显示加载动画逻辑,比如设置某个状态来控制显示隐藏
return config;
}, error => {
return Promise.reject(error);
});
以及响应拦截器,对返回的数据进行统一处理或者处理全局的错误提示等:
axios.interceptors.response.use(response => {
// 比如对返回数据进行格式校验等操作
return response;
}, error => {
// 统一处理错误,比如根据不同的错误状态码显示不同的提示信息
return Promise.reject(error);
});
十一、样式处理
- 内联样式:
可以直接在 JSX 元素中使用style
属性设置内联样式,不过样式的写法是 JavaScript 对象形式,例如:
function StyledComponent() {
const styles = {
color: 'blue',
fontSize: '20px'
};
return <div style={styles}>This is a styled div</div>;
}
需要注意的是,在样式对象中的属性名采用的是驼峰命名法,和 CSS 中的写法有所不同,比如 background-color
在 JavaScript 对象中要写成 backgroundColor
。而且内联样式的优先级相对较高,如果存在多个样式来源,它会优先应用。
- CSS 样式表(外部样式、CSS 模块等):
- 外部样式:可以像常规网页开发一样,创建
.css
文件,然后在 React 组件中通过import
导入,例如创建styles.css
文件:
- 外部样式:可以像常规网页开发一样,创建
.my-class {
color: green;
background-color: yellow;
}
然后在组件中:
import React from 'react';
import './styles.css';
function MyStyledComponent() {
return <div className="my-class">Styled with external CSS</div>;
}
这种方式比较直观简单,适合整体项目样式的定义,不过容易出现样式冲突问题,尤其是在大型项目中不同组件使用相同的类名时,可能会导致样式互相覆盖。
- CSS 模块:这是一种将样式局部化的方式,避免样式冲突,在创建的
.css
文件后缀名改为.module.css
,然后导入时就会得到一个对象,通过对象属性来应用样式,例如:
/* styles.module.css */
.container {
padding: 20px;
}
在组件中:
import React from 'react';
import styles from './styles.module.css';
function MyStyledComponent() {
return <div className={styles.container}>Styled with CSS module</div>;
}
CSS 模块会自动为每个类名生成唯一的哈希值,使得样式只会应用在对应的组件内,有效避免了样式冲突,在多人协作开发或者组件化程度较高的项目中应用广泛。
十二、高阶组件(HOC - Higher-Order Component)和自定义 Hook(进阶内容)
- 高阶组件:
它是一个函数,接收一个组件作为参数,然后返回一个新的组件,通常用于复用组件逻辑、添加额外功能等。例如,创建一个高阶组件用于给传入的组件添加权限验证功能:
function withAuth(Component) {
return function WrappedComponent(props) {
const isAuthenticated = checkAuth(); // 假设这是一个验证权限的函数
if (isAuthenticated) {
return <Component {...props} />;
} else {
return <p>You are not authorized!</p>;
}
}
}
function MyProtectedComponent() {
return <h2>Protected Content</h2>;
}
const ProtectedComponent = withAuth(MyProtectedComponent);
这样 ProtectedComponent
就是经过权限验证包装后的组件了,只有通过验证才能展示原本的组件内容。高阶组件在 React 中是一种很强大的抽象复用逻辑的方式,但使用时也要注意一些问题,比如不要在高阶组件中随意修改传入组件的 props
结构,避免出现不符合预期的行为;同时如果多个高阶组件嵌套使用,要留意组件的 props
传递和渲染顺序等情况。
- 自定义 Hook:
它是一种复用状态逻辑的方式,让我们可以把组件中相关的状态和逻辑提取出来,方便在多个组件中使用。例如,创建一个自定义 Hook 用于获取窗口大小:
import { useState, useEffect } from 'react';
function useWindowSize() {
const [size, setSize] = useState({
width: window.innerWidth,
height: window.innerHeight
});
useEffect(() => {
const handleResize = () => {
setSize({
width: window.innerWidth,
height: window.innerHeight
});
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return size;
}
function WindowSizeComponent() {
const size = useWindowSize();
return (
<div>
<p>Window width: {size.width}</p>
<p>Window height: {size.height}</p>
</div>
);
}
通过这个自定义 Hook,WindowSizeComponent
就能方便地获取并展示窗口大小信息了,而且其他需要窗口大小信息的组件也可以复用这个 Hook。在创建和使用自定义 Hook 时,要遵循 Hook 的使用规则,比如只能在函数组件的顶层调用 Hook,不能在循环、条件语句或者嵌套函数内调用,这样才能保证 React 能够正确地跟踪 Hook 的状态变化和更新逻辑。
十三、React 性能优化
- 使用
React.memo
(函数组件):React.memo
是一个高阶函数,用于对函数组件进行 “记忆”,避免不必要的重新渲染。它会对组件的props
进行浅比较,如果props
没有变化,就会复用之前渲染的结果,不会重新执行组件函数。例如:
import React from 'react';
function MyComponent(props) {
return <div>{props.value}</div>;
}
export default React.memo(MyComponent);
不过要注意,如果 props
是复杂对象或者数组,浅比较可能无法准确判断是否真正变化了,这时候可能需要结合其他手段(比如自定义比较函数等)来确保正确的渲染控制。
- 使用
shouldComponentUpdate
(类组件):
如前面在生命周期部分提到的,在类组件中可以通过实现shouldComponentUpdate
方法来决定组件是否需要重新渲染。例如:
class MyClassComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
if (this.props.value === nextProps.value && this.state.count === nextState.count) {
return false;
}
return true;
}
render() {
return <div>{this.props.value}</div>;
}
}
这里根据 props
和 state
的特定值来判断是否重新渲染,合理地实现这个方法能避免很多不必要的渲染开销,提升组件性能。
-
避免过度渲染列表:
在渲染列表时,确保给每个列表项添加合适的key
属性,且key
要具有唯一性和稳定性(最好是数据本身的唯一标识,比如数据库中的id
字段),这样 React 能更高效地识别哪些元素发生了变化,只更新需要更新的部分,避免整个列表重新渲染。另外,尽量减少在列表渲染中进行复杂计算或者创建过多的临时对象等操作,这些可能会增加渲染的负担。 -
使用
useCallback
和useMemo
Hooks(函数组件):useCallback
主要用于缓存函数,避免在组件每次重新渲染时都重新创建函数实例,特别是对于作为props
传递给子组件且依赖该函数进行性能优化的情况。例如:
import React, { useState, useCallback } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []);
return <ChildComponent onClick={handleClick} />;
}
function ChildComponent(props) {
return <button onClick={props.onClick}>Click me</button>;
}
useMemo
则用于缓存计算结果,只有当依赖项发生变化时才会重新计算,比如在组件中有比较复杂的计算逻辑且该结果不随每次渲染都改变时,可以使用 useMemo
进行优化。例如:
import React, { useState, useMemo } from 'react';
function ExpensiveCalculationComponent() {
const [number, setNumber] = useState(1);
const result = useMemo(() => {
// 假设这里是一个很复杂的计算逻辑
return number * 10;
}, [number]);
return <div>{result}</div>;
}
十四、React 生态与周边工具
- 状态管理库(如 Redux、MobX 等):
在大型复杂的 React 应用中,仅靠组件自身的state
和props
来管理数据可能会变得很复杂,这时候就可以借助专门的状态管理库。- Redux:它遵循单向数据流的原则,通过
action
(描述发生了什么操作)、reducer
(根据action
来更新状态的纯函数)和store
(存储整个应用的状态)等核心概念来管理应用的全局状态。例如,简单的 Redux 配置如下:
- Redux:它遵循单向数据流的原则,通过
import { createStore } from'redux';
const initialState = {
count: 0
};
function reducer(state = initialState, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
}
const store = createStore(reducer);
export default store;
然后在 React 组件中可以通过 react-redux
库提供的 connect
函数(对于类组件)或者 useSelector
、useDispatch
Hooks(对于函数组件)来连接 Redux 状态和触发动作。
- MobX:采用的是基于响应式编程的方式来管理状态,通过将数据标记为可观察对象,当这些对象变化时,自动更新依赖它们的组件。它相对 Redux 在使用上更加简洁直观,对于一些小型到中型的应用或者对实时性要求较高的应用场景比较适用。
-
代码格式化工具(如 Prettier):
在开发 React 项目时,保持代码格式的一致性很重要,Prettier 就是一款强大的代码格式化工具,它可以自动按照设定的规则对代码进行格式化,支持多种编程语言包括 JavaScript、JSX 等。通常可以在项目中配置.prettierrc
文件来指定格式化的规则,比如缩进风格、语句结尾是否加分号等,然后通过编辑器插件(如 Visual Studio Code 中的 Prettier 插件)或者在命令行中执行prettier --write
命令来对代码进行格式化。 -
代码检查工具(如 ESLint):
ESLint 可以帮助检查代码中是否存在语法错误、不符合规范的代码写法以及潜在的代码质量问题等。可以通过配置.eslintrc
文件来定义项目适用的代码检查规则,比如是否允许使用特定的 JavaScript 语法、变量命名规范等。在 React 项目中,还可以结合一些 React 相关的 ESLint 插件(如eslint-plugin-react
)来检查 React 特定的代码规范问题,例如是否正确使用props
、state
等。 -
UI 组件库(如 Ant Design、Material-UI 等):
为了加快项目开发速度、保持界面风格的一致性,很多时候会选用现成的 UI 组件库。- Ant Design:是阿里巴巴开源的一套企业级 UI 组件库,提供了丰富的组件,涵盖了从基础的按钮、输入框到复杂的表格、树形结构等各类组件,并且有完善的样式和交互设计,同时支持国际化、主题定制等功能,在国内应用非常广泛。例如使用其按钮组件:
import React from'react';
import { Button } from 'antd';
function MyButtonComponent() {
return <Button type="primary">Click me</Button>;
}
- Material-UI:是基于 Google 的 Material Design 风格打造的 UI 组件库,具有简洁美观、交互体验好等特点,提供了大量符合 Material Design 规范的组件,在国际上有众多用户。例如使用其文本框组件:
import React from'react';
import TextField from '@material-ui/core/TextField';
function MyTextFieldComponent() {
return <TextField label="Input" />;
}
通过对这些 React 生态中的工具和库的合理运用,可以进一步提升 React 项目的开发效率、代码质量以及用户体验。
希望这份完整的学习笔记能帮助你更好地学习和掌握 React 开发相关知识呀,学习过程中一定要多实践、多做一些小项目来巩固理解哦
原文地址:https://blog.csdn.net/2401_82456630/article/details/144069868
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!