这是一个完整的React学习平台,专为React初学者和进阶开发者设计。项目包含了从基础概念到高级应用的全面教程,以及丰富的交互式示例和实战项目。
react-learning-hub/
├── public/
│ └── index.html # HTML入口文件
├── src/
│ ├── components/ # React组件
│ │ ├── LearningCenter.js # 学习中心主组件
│ │ └── LearningCenter.css # 学习中心样式
│ ├── App.js # 主应用组件
│ ├── App.css # 应用样式
│ ├── index.js # React入口文件
│ └── index.css # 全局样式
├── package.json # 项目配置和依赖
├── .gitignore # Git忽略文件
└── README.md # 项目说明文档
在项目根目录下运行:
npm installnpm start项目将在浏览器中打开 http://localhost:3000
npm run buildJSX是JavaScript的语法扩展,让你可以在JavaScript中写类似HTML的代码。
// JSX语法
const element = <h1>Hello, {name}!</h1>;
// 编译后的JavaScript
const element = React.createElement('h1', null, 'Hello, ', name, '!');JSX规则:
- 必须有一个根元素
- 使用className而不是class
- 事件名使用驼峰命名法
- 可以嵌入JavaScript表达式用
{}
组件是React应用的基本构建块。有两种写法:函数组件和类组件。
function MyComponent() {
return <div>Hello React!</div>;
}class MyComponent extends React.Component {
render() {
return <div>Hello React!</div>;
}
}import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>计数: {count}</p>
<button onClick={() => setCount(count + 1)}>
增加
</button>
</div>
);
}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>
);
}
}Props是组件间传递数据的方式,类似于函数的参数。
// 函数组件
function Welcome(props) {
return <h1>Hello, {props.name}!</h1>;
}
// 类组件
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
// 使用组件
<Welcome name="张三" />
<Welcome name="李四" />React使用驼峰命名法处理事件,如onClick、onChange等。
function Button() {
const handleClick = (e) => {
e.preventDefault(); // 阻止默认行为
alert('按钮被点击了!');
};
return <button onClick={handleClick}>点击我</button>;
}function Greeting({ isLoggedIn, username }) {
if (isLoggedIn) {
return <h1>欢迎回来, {username}!</h1>;
}
return <h1>请先登录</h1>;
}
// 或者使用三元运算符
function Greeting({ isLoggedIn, username }) {
return (
<div>
{isLoggedIn ? (
<h1>欢迎回来, {username}!</h1>
) : (
<h1>请先登录</h1>
)}
</div>
);
}function TodoList({ todos }) {
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
}- 使用ES6 class语法
- 有完整的生命周期方法
- 使用this.state和this.setState
- 代码相对冗长
class MyClassComponent extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
componentDidMount() {
console.log('组件已挂载');
}
handleClick = () => {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<div>
<p>计数: {this.state.count}</p>
<button onClick={this.handleClick}>点击</button>
</div>
);
}
}- 函数式编程风格
- 使用useState、useEffect等Hooks
- 代码更简洁
- React官方推荐的现代写法
import React, { useState, useEffect } from 'react';
function MyHooksComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('组件已挂载');
}, []);
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<p>计数: {count}</p>
<button onClick={handleClick}>点击</button>
</div>
);
}- 新手推荐:从Hooks组件开始学习
- 现代项目:优先使用Hooks组件
- 遗留项目:可以逐步迁移到Hooks
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const [name, setName] = useState('');
return (
<div>
<p>计数: {count}</p>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="输入姓名"
/>
<button onClick={() => setCount(count + 1)}>增加</button>
</div>
);
}import { useState, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// 组件挂载时执行
fetchData();
}, []); // 空依赖数组,只执行一次
useEffect(() => {
// 当data变化时执行
console.log('数据已更新:', data);
}, [data]); // 依赖data
const fetchData = async () => {
setLoading(true);
const response = await fetch('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/api/data');
const result = await response.json();
setData(result);
setLoading(false);
};
if (loading) return <div>加载中...</div>;
return <div>{JSON.stringify(data)}</div>;
}import { createContext, useContext } from 'react';
const ThemeContext = createContext();
function App() {
return (
<ThemeContext.Provider value="dark">
<Header />
</ThemeContext.Provider>
);
}
function Header() {
const theme = useContext(ThemeContext);
return <div className={`header ${theme}`}>头部</div>;
}src/
├── components/ # 可复用组件
│ ├── Button/
│ │ ├── Button.js
│ │ ├── Button.css
│ │ └── Button.test.js
│ └── Header/
├── pages/ # 页面组件
│ ├── Home.js
│ ├── About.js
│ └── Contact.js
├── hooks/ # 自定义Hooks
│ ├── useLocalStorage.js
│ └── useApi.js
├── utils/ # 工具函数
│ ├── helpers.js
│ └── constants.js
├── services/ # API服务
│ └── api.js
├── context/ # Context提供者
│ └── AppContext.js
├── App.js
├── App.css
└── index.js
import { useState } from 'react';
function ContactForm() {
const [formData, setFormData] = useState({
name: '',
email: '',
message: ''
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({
...prev,
[name]: value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
console.log('提交数据:', formData);
};
return (
<form onSubmit={handleSubmit}>
<input
name="name"
value={formData.name}
onChange={handleChange}
placeholder="姓名"
/>
<input
name="email"
type="email"
value={formData.email}
onChange={handleChange}
placeholder="邮箱"
/>
<textarea
name="message"
value={formData.message}
onChange={handleChange}
placeholder="消息"
/>
<button type="submit">提交</button>
</form>
);
}// hooks/useCounter.js
import { useState } from 'react';
export function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
const reset = () => setCount(initialValue);
return { count, increment, decrement, reset };
}
// 使用自定义Hook
function Counter() {
const { count, increment, decrement, reset } = useCounter(0);
return (
<div>
<p>计数: {count}</p>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<button onClick={reset}>重置</button>
</div>
);
}class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.log('错误详情:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h1>出现错误,请刷新页面重试</h1>;
}
return this.props.children;
}
}- ES7+ React/Redux/React-Native snippets
- Prettier - Code formatter
- ESLint
- Auto Rename Tag
- Bracket Pair Colorizer
- React Developer Tools
- React Developer Tools (Chrome/Firefox扩展)
- Redux DevTools (如果使用Redux)
- React基础教程 - 学习组件、状态、属性
- React Hooks - 学习useState、useEffect等
- React Router - 学习页面路由
- 状态管理 - 学习Redux或Context API
- 学习JSX语法 - React的模板语法
- 掌握组件生命周期 - 了解组件从创建到销毁的过程
- 学习Hooks - 现代React的函数式编程方式
- 实践项目 - 尝试构建更复杂的应用
# 安装依赖
npm install
# 启动开发服务器
npm start
# 运行测试
npm test
# 构建生产版本
npm run build
# 弹出配置(不推荐新手使用)
npm run ejectA: 检查是否正确使用了useState或useEffect,确保状态更新触发了重新渲染。
A: 使用浏览器开发者工具,安装React Developer Tools扩展,使用console.log输出调试信息。
A: 现代React推荐使用函数组件配合Hooks,类组件主要用于遗留代码。
- Fork 这个项目
- 创建你的特性分支 (
git checkout -b feature/AmazingFeature) - 提交你的更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 打开一个 Pull Request
这个项目使用 MIT 许可证 - 查看 LICENSE 文件了解详情。
如果你有任何问题或建议,请通过以下方式联系:
- 邮箱: your.email@example.com
- GitHub: [你的GitHub用户名]
Happy Coding! 🎉