reactjs(超详细)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
- 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
2. ReactJS 的核心概念
ReactJS 是由 Facebook(现 Meta)开发的 JavaScript 库,专注于构建用户界面。它以组件化、单向数据流和高效渲染著称,成为现代前端开发的主流工具。对于编程初学者而言,理解其核心概念是掌握 ReactJS 的关键。
2.1 组件化:构建界面的乐高积木
ReactJS 的核心思想是“一切皆组件”。组件是独立且可复用的代码块,类似于乐高积木——你可以将复杂界面拆解为多个小组件,再通过组合这些组件构建完整的页面。例如,一个电商网站的购物车功能可以拆分为“商品列表组件”“商品卡片组件”和“结算按钮组件”。
组件的优势:
- 可维护性:修改一个组件不会影响其他部分;
- 复用性:相同逻辑的组件可在不同页面重复使用;
- 协作友好:团队成员可独立开发不同组件。
示例:一个简单的按钮组件
function MyButton({ label }) {
return <button>{label}</button>;
}
// 使用组件
<MyButton label="点击我" />
2.2 状态(State)与属性(Props)
ReactJS 中,状态(State)和属性(Props)是数据流动的核心。
状态(State):组件的“记忆”
状态是组件内部管理的数据,例如用户输入的表单内容或计时器的当前时间。当状态变化时,组件会自动重新渲染。
属性(Props):父组件传递的“指令”
Props 是父组件传递给子组件的数据,用于控制子组件的行为。例如,父组件可以传递一个 isDisabled
prop 来禁用子按钮。
对比表格:
| 特征 | State | Props |
|--------------|---------------------------|--------------------------|
| 来源 | 组件内部定义 | 由父组件传递 |
| 可修改性 | 可通过 setState
或 Hooks 修改 | 只读,不可直接修改 |
| 用途 | 管理组件自身状态 | 接收外部数据或指令 |
示例:使用 State 和 Props
// 父组件
function Parent() {
return <Child message="Hello" />;
}
// 子组件
function Child({ message }) {
const [count, setCount] = useState(0);
return (
<div>
<p>{message}</p>
<button onClick={() => setCount(count + 1)}>Count: {count}</button>
</div>
);
}
2.3 虚拟 DOM 与高效渲染
ReactJS 通过虚拟 DOM(Virtual DOM)优化渲染性能。当数据变化时,ReactJS 会先在内存中生成新的虚拟 DOM 树,通过对比新旧树的差异,再仅更新实际需要变化的 DOM 节点,避免全页面重绘。
比喻:
虚拟 DOM 就像一张地图,程序员看到的是地图的变化,而实际城市(真实 DOM)只更新必要的区域。
示例:对比直接操作 DOM 与 ReactJS
// 直接操作 DOM(低效)
document.getElementById("counter").innerHTML = count;
// ReactJS 方式(高效)
function Counter() {
const [count, setCount] = useState(0);
return <div>{count}</div>;
}
3. 函数组件与类组件:选择适合的开发模式
ReactJS 支持函数组件和类组件两种开发模式,但函数组件结合 Hooks 是当前的主流实践。
3.1 函数组件:简洁与现代
函数组件是轻量级的函数,接收 Props 并返回 JSX。通过 React Hooks(如 useState
、useEffect
)可管理状态和副作用。
示例:函数组件与 Hooks
function Timer() {
const [time, setTime] = useState(new Date().toLocaleTimeString());
useEffect(() => {
const interval = setInterval(() => {
setTime(new Date().toLocaleTimeString());
}, 1000);
return () => clearInterval(interval); // 清理副作用
}, []);
return <div>当前时间:{time}</div>;
}
3.2 类组件:兼容与传统
类组件基于 ES6 类语法,需继承 React.Component
并实现 render()
方法。状态通过 this.state
和 this.setState()
管理。
示例:类组件实现计时器
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = { time: new Date().toLocaleTimeString() };
}
componentDidMount() {
this.interval = setInterval(() => {
this.setState({ time: new Date().toLocaleTimeString() });
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return <div>当前时间:{this.state.time}</div>;
}
}
3.3 为什么推荐函数组件?
- 代码更简洁:无需
class
或this
关键字; - Hooks 扩展性:通过
useState
、useEffect
等 Hook 可灵活管理复杂逻辑; - 未来趋势:React 团队持续优化 Hooks,新特性优先支持函数组件。
4. 组件间通信:从 Props 到 Context API
在复杂应用中,组件需要相互通信。ReactJS 提供了多种方式实现数据传递,包括 Props 针对传递、Refs 和 Context API。
4.1 Props 针对传递:父子组件直接通信
父子组件通过 Props 传递数据,但深层嵌套可能导致 Props 链式传递(Prop Drilling)。
示例:父到子的 Props 传递
function Parent() {
return <Child message="来自父组件的问候" />;
}
function Child({ message }) {
return <p>{message}</p>;
}
4.2 Context API:跨越层级共享数据
当多个组件需要访问同一数据(如用户认证信息)时,使用 Context API 可避免 Props 链式传递。
示例:使用 Context API 管理主题
// 创建 Context
const ThemeContext = React.createContext();
// 提供者组件
function ThemeProvider({ children }) {
const [theme, setTheme] = useState("light");
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
// 消费 Context
function ThemedButton() {
const { theme } = useContext(ThemeContext);
return <button style={{ backgroundColor: theme === "dark" ? "black" : "white" }}>按钮</button>;
}
4.3 Refs:直接访问 DOM 或组件实例
Refs 允许直接操作 DOM 元素或 React 组件实例,常用于处理表单输入或焦点控制。
示例:通过 Ref 获取输入框值
function Login() {
const inputRef = useRef();
const handleSubmit = () => {
console.log("用户名:", inputRef.current.value);
};
return (
<div>
<input ref={inputRef} type="text" placeholder="用户名" />
<button onClick={handleSubmit}>登录</button>
</div>
);
}
5. 高阶组件(HOC)与渲染 props:复用逻辑的高级技巧
ReactJS 的灵活性体现在其复用逻辑的能力上,高阶组件(HOC)和渲染 props 是两种常见模式。
5.1 高阶组件:组件工厂
HOC 是一个函数,接收组件作为参数并返回一个新组件,常用于封装公共逻辑(如权限验证或数据获取)。
示例:使用 HOC 添加加载状态
function withLoading(WrappedComponent) {
return function WithLoading(props) {
const [isLoading, setLoading] = useState(true);
useEffect(() => {
setTimeout(() => setLoading(false), 1000); // 模拟异步请求
}, []);
return isLoading ? <div>加载中...</div> : <WrappedComponent {...props} />;
};
}
// 使用 HOC
const LoadingPost = withLoading(Post);
5.2 渲染 props:通过函数传递逻辑
渲染 props 通过 Props 传递函数,允许父组件控制子组件的渲染逻辑。
示例:使用渲染 props 传递主题
function ThemeProvider({ children }) {
const [theme, setTheme] = useState("light");
return children({ theme, toggleTheme: () => setTheme(theme === "light" ? "dark" : "light") });
}
// 使用渲染 props
<ThemeProvider>
{({ theme, toggleTheme }) => (
<div>
<button onClick={toggleTheme}>切换主题</button>
<p style={{ color: theme === "dark" ? "white" : "black" }}>当前主题:{theme}</p>
</div>
)}
</ThemeProvider>
6. ReactJS 生态系统:从路由到状态管理
ReactJS 本身轻量,但其生态系统提供了丰富的工具链,如路由库 React Router、状态管理库 Redux 等。
6.1 React Router:构建单页应用(SPA)
React Router 是 React 的路由解决方案,支持动态路由和页面导航。
示例:定义基础路由
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
function App() {
return (
<Router>
<nav>
<Link to="/">首页</Link>
<Link to="/about">关于</Link>
</nav>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
</Router>
);
}
6.2 状态管理:Redux 或 React Query
对于复杂应用,单组件状态可能不足以管理全局数据。Redux 通过集中式状态树和 reducer 管理状态,而 React Query 则专注于 API 数据获取和缓存。
示例:使用 React Query 获取数据
function UserList() {
const { data, error, isLoading } = useQuery("users", fetchUsers);
if (isLoading) return <div>加载中...</div>;
if (error) return <div>加载失败</div>;
return (
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
7. ReactJS 的最佳实践与性能优化
掌握核心概念后,开发者还需关注代码质量和性能优化。
7.1 关键优化技巧
- 避免不必要的渲染:使用
React.memo
或useMemo
缓存组件或计算结果; - 优化列表渲染:为列表项添加
key
属性,帮助 React 识别变化; - 代码分割:使用动态导入(
import()
)实现代码按需加载。
示例:使用 React.memo
缓存组件
const MemoizedComponent = React.memo(function Component({ data }) {
// 仅在 data 变化时重新渲染
return <div>{data}</div>;
});
7.2 开发工具:React Developer Tools
Chrome 的 React Developer Tools 插件可查看组件树、状态和 Props,是调试的必备工具。
8. 结论:为什么选择 ReactJS?
ReactJS 通过组件化、虚拟 DOM 和丰富的生态,成为构建现代前端应用的首选工具。无论是初学者还是中级开发者,掌握其核心概念后,可以快速构建高效、可维护的用户界面。随着 Hooks 和 TypeScript 的普及,ReactJS 的学习曲线持续降低,而其社区的支持和更新速度也确保了其长期生命力。
开始你的 ReactJS 之旅吧!