React学习教程,从入门到精通, React 嵌套组件语法知识点(10)

发布于:2025-09-05 ⋅ 阅读:(19) ⋅ 点赞:(0)

React 嵌套组件语法知识点

React 是一个用于构建用户界面的 JavaScript 库,其核心概念之一是组件化。组件可以相互嵌套,形成复杂的用户界面结构。以下将详细介绍 React 嵌套组件的语法知识点,并通过一个详细的案例代码进行说明。

目录

  1. 组件基础
  2. 函数组件 vs 类组件
  3. 嵌套组件
  4. 属性(Props)
  5. 状态(State)
  6. 事件处理
  7. 生命周期方法
  8. 案例代码

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 提供了生命周期方法,如 componentDidMountcomponentDidUpdatecomponentWillUnmount。在函数组件中,使用 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;

代码说明

  1. 入口文件 index.js:渲染 App 组件到页面的根元素。

  2. App.jsx

    • 使用 useState 管理待办事项列表。
    • 定义 addTodotoggleTododeleteTodo 方法,用于添加、切换完成状态和删除待办事项。
    • 渲染 AddTodo 组件和 TodoList 组件,并传递相应的 props。
  3. AddTodo.jsx

    • 管理输入框的状态。
    • 处理表单提交,调用 addTodo 方法添加新的待办事项。
  4. TodoList.jsx

    • 接收 todos 列表和操作方法作为 props。
    • 渲染每个 TodoItem 组件。
  5. TodoItem.jsx

    • 显示待办事项的文本和完成状态。
    • 处理复选框的点击事件,调用 toggleTodo 方法切换完成状态。
    • 处理删除按钮的点击事件,调用 deleteTodo 方法删除待办事项。

运行效果

运行该项目后,用户可以:

  • 添加待办事项:在输入框中输入文本并点击“添加”按钮。
  • 切换完成状态:点击复选框,文本会显示删除线。
  • 删除待办事项:点击“删除”按钮,删除对应的待办事项。

总结

通过以上知识点和案例代码,我们了解了 React 中嵌套组件的基本概念和实现方法。组件的嵌套不仅提高了代码的可维护性和可重用性,还使得复杂的用户界面结构更加清晰。在实际开发中,合理地组织组件结构对于构建高效的应用至关重要。


网站公告

今日签到

点亮在社区的每一天
去签到