• react传参有哪些常用方法?--Props,Context API和Redux全局管理


    React 中,父子组件之间的传参主要通过以下几种方式实现:
                 1) Props 传递:父子传参
                 2)Context  API: 跨多层组件传递数据
                 3) Redux: 全局状态管理库

    一、Props父子组件传参(传值、传方法)

    1. 父传子数据

    1. // 父组件
    2. <ChildComponent someProp={someValue} />
    3. // 子组件
    4. function ChildComponent(props) {
    5. const { someProp } = props; // 使用props获取父组件传的值
    6. }

    2.子传父 (回调函数)

     父组件将一个或多个回调函数作为 props 传递给子组件,子组件在需要时调用这些函数,将数据回传给父组件。

    1. // 父组件
    2. const handleData = (data) => {
    3. // 处理数据
    4. };
    5. <ChildComponent onDataToParent={handleData} />
    6. // 子组件
    7. function ChildComponent(props) {
    8. const { onDataToParent } = props; // 使用props获取到父组件传过来的参数
    9. const sendData = (data) => {
    10. onDataToParent(data); // 子组件调用父组件传过来的函数,回传给父组件
    11. };
    12. }

    3. 父子传参的demo

    父组件:

    1. import React from 'react';
    2. import ChildComponent from './ChildComponent.tsx';
    3. function ParentComponent() {
    4. // 定义父组件的状态和处理函数
    5. const [childData, setChildData] = React.useState('Initial Data');
    6. // 定义一个处理函数,用于接收子组件传递的数据
    7. const handleDataFromChild = (newData) => {
    8. setChildData(newData);
    9. alert(`Data from child: ${newData}`);
    10. };
    11. return (
    12. <div>
    13. <h1>Parent Componenth1>
    14. <p>Current Data: {childData}p>
    15. {/* 将数据和回调函数作为 props 传递给子组件 */}
    16. <ChildComponent
    17. childData={childData}
    18. onDataToParent={handleDataFromChild}
    19. />
    20. div>
    21. );
    22. }
    23. export default ParentComponent;

    子组件ChildComponent.tsx:

    1. import React from 'react';
    2. function ChildComponent(props) {
    3. // 从 props 中解构出子组件接收到的数据和回调函数
    4. const { childData, onDataToParent } = props;
    5. // 定义一个函数,用于更新子组件的状态,并触发回调函数
    6. const updateData = () => {
    7. const newData = `Updated Data from Child: ${new Date().toLocaleTimeString()}`;
    8. onDataToParent(newData); // 调用父组件传递的回调函数
    9. };
    10. return (
    11. <div>
    12. <h2>Child Componenth2>
    13. <p>Received Data: {childData}p>
    14. {/* 一个按钮,点击时调用 updateData 函数 */}
    15. <button onClick={updateData}>Send Data to Parentbutton>
    16. div>
    17. );
    18. }
    19. export default ChildComponent;

    二、Context API

    在react中使用Context API 可以轻松的在组件数间传递数据,无需听过每一层的手动传递props。

    步骤 1: 创建 Context 

    首先,使用 React.createContext 创建一个新的 Context 对象。

    utils/context.js文件:

    1. import React from 'react';
    2. const MyContext = React.createContext('default value');
    3. export default MyContext;

    步骤 2: 提供 Context 值

    然后,在组件树的适当层级使用 来包裹子组件,并通过 value 属性传递数据。

    1. import React from 'react';
    2. import MyContext from '../../utils/context.js';
    3. import ChildComponent from './ChildComponent.jsx'
    4. function App() {
    5. const appData = { message: 'Hello, World!', number: 42 };
    6. return (
    7. <MyContext.Provider value={appData}>
    8. <ChildComponent />
    9. MyContext.Provider>
    10. );
    11. }
    12. export default App;

    在子组件ChildComponent.js中,使用 useContext Hook 来访问 Context 的值。

    1. import React, { useContext } from 'react';
    2. import MyContext from '../../utils/context.js';
    3. function ChildComponent() {
    4. const { message, number } = useContext(MyContext); // 接受传参的值
    5. return (
    6. <div>
    7. <p>{message}p>
    8. <p>{number}p>
    9. div>
    10. );
    11. }
    12. export default ChildComponent;

    附加功能:动态 Context 值

    如果你需要在应用中动态更改 Context 的值,可以在 Provider 中使用状态来实现。

    1. // App.js
    2. import React, { useState } from 'react';
    3. import MyContext from '../../utils/context.js';
    4. import ChildComponent from './ChildComponent.tsx';
    5. export default function App() {
    6. const [appData, setAppData] = useState({ message: 'Hello, World!', number: 42 });
    7. const updateMessage = (newMessage, newNum) => {
    8. setAppData((prev) => ({ ...prev, message: newMessage, number: newNum }));
    9. };
    10. return (
    11. <MyContext.Provider value={{ ...appData, updateMessage }}>
    12. <ChildComponent />
    13. MyContext.Provider>
    14. );
    15. }

    在子组件ChildComponent.tsx中,你可以使用提供的函数来更新 Context 的值。

    1. // ChildComponent.js
    2. import React, { useContext } from 'react';
    3. import MyContext from '../../utils/context.js';
    4. export default function ChildComponent() {
    5. const { message, number, updateMessage } = useContext(MyContext);
    6. const handleClick = () => {
    7. updateMessage('New message from child!', 3333);
    8. };
    9. return (
    10. <div>
    11. <p>{message}p>
    12. <p>{number}p>
    13. <button onClick={handleClick}>Update Messagebutton>
    14. div>
    15. );
    16. }

    三、Redux  全局状态管理

    1. redux是什么?

    1、redux是一个专门用于做状态管理的js库(不是react插件库)。
    2、它可以用在react,angular,vue等项目中,但基本与react配合使用。
    3、作用:集中式管理react应用中多个组件共享的状态。
    4、 redux只负责管理状态,至于状态的改变驱动着页面的展示,要靠我们自己写

     2. 什么情况下需要使用redux

    1、某个组件的状态,需要让其他组件可以随时拿到(共享)。
    2、一个组件需要改变另一个组件的状态(通信)。
    3、总体原则:能不用就不用,如果不用比较吃力才考虑使用。

    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 

    4.工作原理

    Redux 的工作流程遵循单向数据流原则:

    1. View 发起 Action

      • 用户与界面交互,触发一个 Action。
    2. Dispatch Action

      • Action 被发送到 Store。
    3. Reducer 处理 Action

      • Store 调用 Reducer,传入当前 State 和 Action,Reducer 返回新的 State。
    4. State 更新

      • Store 更新 State,任何订阅了 Store 的组件都会收到通知并重新渲染。
    5. View 更新

      • 组件从 Store 中读取新的状态,并更新 UI。

    5. demo示例

    安装redux:

    npm install redux

     stoer/index.ts 文件

    1. import { createStore, combineReducers } from "redux";
    2. // import UserReducer from "./user/reducer.ts";
    3. import todoReducer from './todo/todoReducer.ts'; //
    4. const reducer = combineReducers({
    5. // user: UserReducer,
    6. todos: todoReducer,
    7. });
    8. // 创建数据公共的存储区域
    9. const store = createStore(
    10. reducer, // 辅助管理数据,reducer是一个纯函数,不需要直接修改state
    11. );
    12. export default store;

    store/todo/action.ts

    1. // 定义action类型
    2. export const ADD_TODO = 'ADD_TODO';
    3. export const DELETE_TODO = 'DELETE_TODO';
    4. export const TOGGLE_TODO = 'TOGGLE_TODO';
    5. // 定义action creators
    6. export const addTodo = (text) => ({
    7. type: ADD_TODO,
    8. payload: {
    9. id: new Date().getTime(),
    10. text,
    11. completed: false,
    12. },
    13. });
    14. export const deleteTodo = (id) => ({
    15. type: DELETE_TODO,
    16. payload: { id },
    17. });
    18. export const toggleTodo = (id) => ({
    19. type: TOGGLE_TODO,
    20. payload: { id },
    21. });

    store/todo/todoReducer.ts

    1. import { ADD_TODO, DELETE_TODO, TOGGLE_TODO } from './action.ts';
    2. // 定义初始状态
    3. const initialState = [];
    4. // 定义reducer函数
    5. const todoReducer = (state = initialState, action) => {
    6. switch (action.type) {
    7. case ADD_TODO:
    8. return [...state, action.payload];
    9. case DELETE_TODO:
    10. return state.filter(todo => todo.id !== action.payload.id);
    11. case TOGGLE_TODO:
    12. return state.map(todo => {
    13. if (todo.id === action.payload.id) {
    14. return { ...todo, completed: !todo.completed };
    15. }
    16. return todo;
    17. });
    18. default:
    19. return state;
    20. }
    21. };
    22. export default todoReducer;

    页面使用

    pages/reducer/index.tsx

    1. import React from 'react';
    2. import { Button, message } from 'antd';
    3. import { useSelector, useDispatch } from 'react-redux';
    4. import { addTodo, deleteTodo, toggleTodo } from '../../store/todo/action.ts';
    5. const TodoListStyles = {
    6. container: {
    7. padding: '20px',
    8. },
    9. todoItem: {
    10. listStyleType: 'none',
    11. marginBottom: '10px',
    12. },
    13. };
    14. function TodoList() {
    15. // useSelector Hook,用于从 Redux store 中选择数据。接收一个函数作为参数
    16. // 使用 useSelector 钩子从 Redux store 获取 todos 状态
    17. const todos = useSelector((state) => state.todos);
    18. const dispatch = useDispatch();
    19. // 添加待办事项
    20. const handleAddTodo = () => {
    21. const text = prompt('请输入Todo项的内容:');
    22. if (text) {
    23. dispatch(addTodo(text));
    24. }
    25. };
    26. // 删除待办事项
    27. const handleDeleteTodo = (id) => {
    28. dispatch(deleteTodo(id));
    29. };
    30. // 切换待办事项的完成状态
    31. const handleToggleTodo = (id) => {
    32. dispatch(toggleTodo(id));
    33. };
    34. return (
    35. <div style={TodoListStyles.container}>
    36. <h2>Todo Listh2>
    37. <ul>
    38. {todos.map((todo) => (
    39. <li key={todo.id} style={TodoListStyles.todoItem}>
    40. <span
    41. style={{
    42. textDecoration: todo.completed ? 'line-through' : 'none',
    43. cursor: 'pointer',
    44. }}
    45. onClick={() => handleToggleTodo(todo.id)}
    46. >
    47. {todo.text}
    48. span>
    49. <Button
    50. type="link"
    51. danger
    52. style={{ marginLeft: '10px' }}
    53. onClick={() => handleDeleteTodo(todo.id)}
    54. >
    55. 删除
    56. Button>
    57. li>
    58. ))}
    59. ul>
    60. <Button onClick={handleAddTodo}>添加TodoButton>
    61. div>
    62. );
    63. }
    64. export default TodoList;

  • 相关阅读:
    【JavaWeb】登陆页面
    idea2020.1 安装 kubectl win10
    实现一个简单的控制台版用户登陆程序, 程序启动提示用户输入用户名密码. 如果用户名密码出错, 使用自定义异常的方式来处理
    服务器容器化-docker(全)
    46、TCP的“三次握手”
    毕设 电影网论文
    简化版ssl/tls 自签证书
    深入解析 qsort 排序(上),它为什么是万能排序?
    RabbitMQ入门
    【VUE复习·8】v-if;v-show高级
  • 原文地址:https://blog.csdn.net/weixin_44834981/article/details/139677933