React 嵌套组件语法知识点
React 是一个用于构建用户界面的 JavaScript 库,其核心概念之一是组件化。组件可以相互嵌套,形成复杂的用户界面结构。以下将详细介绍 React 嵌套组件的语法知识点,并通过一个详细的案例代码进行说明。
目录
1. 组件基础
在 React 中,组件是构建用户界面的基本单元。组件可以是一个函数或一个类,接受输入(props),并返回一个 React 元素。
组件分类
- 函数组件(Functional Components):使用 JavaScript 函数定义的组件。
- 类组件(Class Components):使用 ES6 类定义的组件。
2. 函数组件 vs 类组件
函数组件
// 函数组件示例
import React from 'react';
const Greeting = (props) => {
return <h1>Hello, {props.name}!</h1>;
};
export default Greeting;
类组件
// 类组件示例
import React, { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
export default Greeting;
注意:随着 React Hooks 的引入,函数组件的功能得到了极大的增强,许多情况下推荐使用函数组件。
3. 嵌套组件
嵌套组件指的是在一个组件内部使用另一个组件。这有助于将复杂的 UI 分解成更小的、可重用的部分。
示例
// ParentComponent.jsx
import React from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = () => {
return (
<div>
<h1>Parent Component</h1>
<ChildComponent />
</div>
);
};
export default ParentComponent;
// ChildComponent.jsx
import React from 'react';
const ChildComponent = () => {
return <p>This is a child component.</p>;
};
export default ChildComponent;
4. 属性(Props)
Props 是组件的输入,用于从父组件向子组件传递数据。Props 是只读的,组件不能修改自身的 props。
示例
// ParentComponent.jsx
import React from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = () => {
return (
<div>
<h1>Parent Component</h1>
<ChildComponent name="Alice" age={25} />
</div>
);
};
export default ParentComponent;
// ChildComponent.jsx
import React from 'react';
const ChildComponent = (props) => {
return (
<div>
<p>Name: {props.name}</p>
<p>Age: {props.age}</p>
</div>
);
};
export default ChildComponent;
5. 状态(State)
State 是组件内部维护的数据。状态的变化会触发组件的重新渲染。函数组件使用 Hooks(如 useState
)来管理状态。
示例
// Counter.jsx
import React, { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default Counter;
6. 事件处理
React 中处理事件的方式与 DOM 事件类似,但使用驼峰命名法,并且事件处理函数作为 props 传递。
示例
// Button.jsx
import React from 'react';
const Button = ({ onClick, label }) => {
return <button onClick={onClick}>{label}</button>;
};
export default Button;
// App.jsx
import React, { useState } from 'react';
import Button from './Button';
const App = () => {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<h1>Count: {count}</h1>
<Button onClick={handleClick} label="Increment" />
</div>
);
};
export default App;
7. 生命周期方法
对于类组件,React 提供了生命周期方法,如 componentDidMount
、componentDidUpdate
和 componentWillUnmount
。在函数组件中,使用 Hooks(如 useEffect
)来管理副作用。
类组件生命周期示例
// LifecycleComponent.jsx
import React, { Component } from 'react';
class LifecycleComponent extends Component {
componentDidMount() {
console.log('组件已挂载');
}
componentDidUpdate() {
console.log('组件已更新');
}
componentWillUnmount() {
console.log('组件即将卸载');
}
render() {
return <h1>Lifecycle Component</h1>;
}
}
export default LifecycleComponent;
函数组件使用 useEffect
示例
// EffectComponent.jsx
import React, { useState, useEffect } from 'react';
const EffectComponent = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('组件挂载或更新');
return () => {
console.log('组件即将卸载');
};
}, [count]);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default EffectComponent;
8. 案例代码
以下是一个包含嵌套组件、属性传递、状态管理和事件处理的完整案例。该案例展示了一个简单的待办事项(Todo)应用。
项目结构
src/
│
├── App.jsx
├── TodoList.jsx
├── TodoItem.jsx
├── AddTodo.jsx
└── index.js
1. index.js
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
2. App.jsx
// App.jsx
import React, { useState } from 'react';
import TodoList from './TodoList';
import AddTodo from './AddTodo';
const App = () => {
const [todos, setTodos] = useState([
{ id: 1, text: '学习 React', completed: false },
{ id: 2, text: '练习编程', completed: true },
]);
const addTodo = (text) => {
const newTodo = {
id: Date.now(),
text,
completed: false,
};
setTodos([...todos, newTodo]);
};
const toggleTodo = (id) => {
const updatedTodos = todos.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
);
setTodos(updatedTodos);
};
const deleteTodo = (id) => {
const filteredTodos = todos.filter((todo) => todo.id !== id);
setTodos(filteredTodos);
};
return (
<div>
<h1>我的待办事项</h1>
<AddTodo addTodo={addTodo} />
<TodoList todos={todos} toggleTodo={toggleTodo} deleteTodo={deleteTodo} />
</div>
);
};
export default App;
3. AddTodo.jsx
// AddTodo.jsx
import React, { useState } from 'react';
const AddTodo = ({ addTodo }) => {
const [text, setText] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
if (text.trim()) {
addTodo(text);
setText('');
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="输入新的待办事项"
/>
<button type="submit">添加</button>
</form>
);
};
export default AddTodo;
4. TodoList.jsx
// TodoList.jsx
import React from 'react';
import TodoItem from './TodoItem';
const TodoList = ({ todos, toggleTodo, deleteTodo }) => {
return (
<ul>
{todos.map((todo) => (
<TodoItem
key={todo.id}
todo={todo}
toggleTodo={toggleTodo}
deleteTodo={deleteTodo}
/>
))}
</ul>
);
};
export default TodoList;
5. TodoItem.jsx
// TodoItem.jsx
import React from 'react';
const TodoItem = ({ todo, toggleTodo, deleteTodo }) => {
return (
<li>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
{todo.text}
</span>
<button onClick={() => deleteTodo(todo.id)}>删除</button>
</li>
);
};
export default TodoItem;
代码说明
入口文件
index.js
:渲染App
组件到页面的根元素。App.jsx
:- 使用
useState
管理待办事项列表。 - 定义
addTodo
、toggleTodo
和deleteTodo
方法,用于添加、切换完成状态和删除待办事项。 - 渲染
AddTodo
组件和TodoList
组件,并传递相应的 props。
- 使用
AddTodo.jsx
:- 管理输入框的状态。
- 处理表单提交,调用
addTodo
方法添加新的待办事项。
TodoList.jsx
:- 接收
todos
列表和操作方法作为 props。 - 渲染每个
TodoItem
组件。
- 接收
TodoItem.jsx
:- 显示待办事项的文本和完成状态。
- 处理复选框的点击事件,调用
toggleTodo
方法切换完成状态。 - 处理删除按钮的点击事件,调用
deleteTodo
方法删除待办事项。
运行效果
运行该项目后,用户可以:
- 添加待办事项:在输入框中输入文本并点击“添加”按钮。
- 切换完成状态:点击复选框,文本会显示删除线。
- 删除待办事项:点击“删除”按钮,删除对应的待办事项。
总结
通过以上知识点和案例代码,我们了解了 React 中嵌套组件的基本概念和实现方法。组件的嵌套不仅提高了代码的可维护性和可重用性,还使得复杂的用户界面结构更加清晰。在实际开发中,合理地组织组件结构对于构建高效的应用至关重要。