在 React 中,父子组件之间的传参主要通过以下几种方式实现:
1) Props 传递:父子传参
2)Context API: 跨多层组件传递数据
3) Redux: 全局状态管理库
- // 父组件
- <ChildComponent someProp={someValue} />
- // 子组件
- function ChildComponent(props) {
- const { someProp } = props; // 使用props获取父组件传的值
- }
父组件将一个或多个回调函数作为 props 传递给子组件,子组件在需要时调用这些函数,将数据回传给父组件。
- // 父组件
- const handleData = (data) => {
- // 处理数据
- };
-
- <ChildComponent onDataToParent={handleData} />
-
- // 子组件
- function ChildComponent(props) {
- const { onDataToParent } = props; // 使用props获取到父组件传过来的参数
-
- const sendData = (data) => {
- onDataToParent(data); // 子组件调用父组件传过来的函数,回传给父组件
- };
- }
父组件:
- import React from 'react';
- import ChildComponent from './ChildComponent.tsx';
-
- function ParentComponent() {
- // 定义父组件的状态和处理函数
- const [childData, setChildData] = React.useState('Initial Data');
-
- // 定义一个处理函数,用于接收子组件传递的数据
- const handleDataFromChild = (newData) => {
- setChildData(newData);
- alert(`Data from child: ${newData}`);
- };
-
- return (
- <div>
- <h1>Parent Componenth1>
- <p>Current Data: {childData}p>
- {/* 将数据和回调函数作为 props 传递给子组件 */}
- <ChildComponent
- childData={childData}
- onDataToParent={handleDataFromChild}
- />
- div>
- );
- }
-
- export default ParentComponent;
子组件ChildComponent.tsx:
- import React from 'react';
-
- function ChildComponent(props) {
- // 从 props 中解构出子组件接收到的数据和回调函数
- const { childData, onDataToParent } = props;
-
- // 定义一个函数,用于更新子组件的状态,并触发回调函数
- const updateData = () => {
- const newData = `Updated Data from Child: ${new Date().toLocaleTimeString()}`;
- onDataToParent(newData); // 调用父组件传递的回调函数
- };
-
- return (
- <div>
- <h2>Child Componenth2>
- <p>Received Data: {childData}p>
- {/* 一个按钮,点击时调用 updateData 函数 */}
- <button onClick={updateData}>Send Data to Parentbutton>
- div>
- );
- }
-
- export default ChildComponent;
在react中使用Context API 可以轻松的在组件数间传递数据,无需听过每一层的手动传递props。

首先,使用 React.createContext 创建一个新的 Context 对象。
utils/context.js文件:
- import React from 'react';
-
- const MyContext = React.createContext('default value');
- export default MyContext;
然后,在组件树的适当层级使用 来包裹子组件,并通过 value 属性传递数据。
-
- import React from 'react';
- import MyContext from '../../utils/context.js';
- import ChildComponent from './ChildComponent.jsx'
-
- function App() {
- const appData = { message: 'Hello, World!', number: 42 };
-
- return (
- <MyContext.Provider value={appData}>
- <ChildComponent />
- MyContext.Provider>
- );
- }
-
- export default App;
在子组件ChildComponent.js中,使用 useContext Hook 来访问 Context 的值。
-
- import React, { useContext } from 'react';
- import MyContext from '../../utils/context.js';
-
- function ChildComponent() {
- const { message, number } = useContext(MyContext); // 接受传参的值
-
- return (
- <div>
- <p>{message}p>
- <p>{number}p>
- div>
- );
- }
-
- export default ChildComponent;
如果你需要在应用中动态更改 Context 的值,可以在 Provider 中使用状态来实现。
- // App.js
- import React, { useState } from 'react';
- import MyContext from '../../utils/context.js';
- import ChildComponent from './ChildComponent.tsx';
-
-
- export default function App() {
- const [appData, setAppData] = useState({ message: 'Hello, World!', number: 42 });
-
- const updateMessage = (newMessage, newNum) => {
- setAppData((prev) => ({ ...prev, message: newMessage, number: newNum }));
- };
-
- return (
- <MyContext.Provider value={{ ...appData, updateMessage }}>
- <ChildComponent />
- MyContext.Provider>
- );
- }
在子组件ChildComponent.tsx中,你可以使用提供的函数来更新 Context 的值。
- // ChildComponent.js
- import React, { useContext } from 'react';
- import MyContext from '../../utils/context.js';
-
- export default function ChildComponent() {
- const { message, number, updateMessage } = useContext(MyContext);
-
- const handleClick = () => {
- updateMessage('New message from child!', 3333);
- };
-
- return (
- <div>
- <p>{message}p>
- <p>{number}p>
- <button onClick={handleClick}>Update Messagebutton>
- div>
- );
- }
1、redux是一个专门用于做状态管理的js库(不是react插件库)。
2、它可以用在react,angular,vue等项目中,但基本与react配合使用。
3、作用:集中式管理react应用中多个组件共享的状态。
4、 redux只负责管理状态,至于状态的改变驱动着页面的展示,要靠我们自己写
1、某个组件的状态,需要让其他组件可以随时拿到(共享)。
2、一个组件需要改变另一个组件的状态(通信)。
3、总体原则:能不用就不用,如果不用比较吃力才考虑使用。
1、Store
store : 用于存储共享数据的仓库
2、State
State 是只读的,任何修改都必须通过触发 actions 来完成。
3、 Action
action : store中所有数据的变化,必须通过派发(dispatch)action来更新
action是一个普通的JavaScript对象,用来描述这次更新的type和content
4、Reducer
reducer : reducer是一个纯函数,接收当前状态和 action,返回新的状态,将state和action联系在一起
reducer做的事情就是将传入的state和action结合起来生成一个新的state

Redux 的工作流程遵循单向数据流原则:
View 发起 Action:
Dispatch Action:
Reducer 处理 Action:
State 更新:
View 更新:
安装redux:
npm install redux
stoer/index.ts 文件
- import { createStore, combineReducers } from "redux";
- // import UserReducer from "./user/reducer.ts";
- import todoReducer from './todo/todoReducer.ts'; //
- const reducer = combineReducers({
- // user: UserReducer,
- todos: todoReducer,
- });
-
- // 创建数据公共的存储区域
- const store = createStore(
- reducer, // 辅助管理数据,reducer是一个纯函数,不需要直接修改state
- );
-
- export default store;
store/todo/action.ts
- // 定义action类型
- export const ADD_TODO = 'ADD_TODO';
- export const DELETE_TODO = 'DELETE_TODO';
- export const TOGGLE_TODO = 'TOGGLE_TODO';
-
- // 定义action creators
- export const addTodo = (text) => ({
- type: ADD_TODO,
- payload: {
- id: new Date().getTime(),
- text,
- completed: false,
- },
- });
-
- export const deleteTodo = (id) => ({
- type: DELETE_TODO,
- payload: { id },
- });
-
- export const toggleTodo = (id) => ({
- type: TOGGLE_TODO,
- payload: { id },
- });
-
store/todo/todoReducer.ts
- import { ADD_TODO, DELETE_TODO, TOGGLE_TODO } from './action.ts';
-
- // 定义初始状态
- const initialState = [];
-
- // 定义reducer函数
- const todoReducer = (state = initialState, action) => {
- switch (action.type) {
- case ADD_TODO:
- return [...state, action.payload];
- case DELETE_TODO:
- return state.filter(todo => todo.id !== action.payload.id);
- case TOGGLE_TODO:
- return state.map(todo => {
- if (todo.id === action.payload.id) {
- return { ...todo, completed: !todo.completed };
- }
- return todo;
- });
- default:
- return state;
- }
- };
-
- export default todoReducer;
-
-
页面使用
pages/reducer/index.tsx
- import React from 'react';
- import { Button, message } from 'antd';
- import { useSelector, useDispatch } from 'react-redux';
- import { addTodo, deleteTodo, toggleTodo } from '../../store/todo/action.ts';
-
- const TodoListStyles = {
- container: {
- padding: '20px',
- },
- todoItem: {
- listStyleType: 'none',
- marginBottom: '10px',
- },
- };
-
- function TodoList() {
- // useSelector Hook,用于从 Redux store 中选择数据。接收一个函数作为参数
- // 使用 useSelector 钩子从 Redux store 获取 todos 状态
- const todos = useSelector((state) => state.todos);
- const dispatch = useDispatch();
-
- // 添加待办事项
- const handleAddTodo = () => {
- const text = prompt('请输入Todo项的内容:');
- if (text) {
- dispatch(addTodo(text));
- }
- };
-
- // 删除待办事项
- const handleDeleteTodo = (id) => {
- dispatch(deleteTodo(id));
- };
-
- // 切换待办事项的完成状态
- const handleToggleTodo = (id) => {
- dispatch(toggleTodo(id));
- };
-
- return (
- <div style={TodoListStyles.container}>
- <h2>Todo Listh2>
- <ul>
- {todos.map((todo) => (
- <li key={todo.id} style={TodoListStyles.todoItem}>
- <span
- style={{
- textDecoration: todo.completed ? 'line-through' : 'none',
- cursor: 'pointer',
- }}
- onClick={() => handleToggleTodo(todo.id)}
- >
- {todo.text}
- span>
- <Button
- type="link"
- danger
- style={{ marginLeft: '10px' }}
- onClick={() => handleDeleteTodo(todo.id)}
- >
- 删除
- Button>
- li>
- ))}
- ul>
- <Button onClick={handleAddTodo}>添加TodoButton>
- div>
- );
- }
-
- export default TodoList;