0

0

React组件间通信:从子组件向父组件传递数据并触发API请求

碧海醫心

碧海醫心

发布时间:2025-10-13 11:28:02

|

1070人浏览过

|

来源于php中文网

原创

React组件间通信:从子组件向父组件传递数据并触发API请求

本教程详细讲解如何在react中实现子组件向父组件传递数据,并利用这些数据触发父组件的api请求。通过将回调函数作为props传递给子组件,并在父组件中使用`usestate`管理状态和`useeffect`处理副作用,我们可以构建一个动态响应用户输入的应用程序。

引言:React组件间通信的核心挑战

在React的组件化开发模式中,数据流通常是单向的,即从父组件流向子组件。然而,在许多实际应用场景中,我们需要子组件(例如用户输入表单)将其产生的数据传递回父组件,以便父组件能够基于这些数据执行相应的操作,比如发起网络请求。本教程将深入探讨如何优雅地实现这一“子传父”的数据通信机制,特别是在需要根据用户输入动态触发API请求的场景。

理解子组件向父组件传递数据的工作原理

React中实现子组件向父组件传递数据的标准模式是利用回调函数。父组件定义一个函数,并将其作为prop传递给子组件。当子组件中发生某个事件(如表单提交、按钮点击)时,它会调用这个通过prop接收到的函数,并将需要传递的数据作为参数传回父组件。父组件接收到数据后,可以更新自身的状态,进而触发UI的重新渲染或执行其他副作用。

第一步:改造子组件 InputField.js

为了让 InputField 组件能够将其内部的输入值传递给父组件,我们需要对其进行修改,使其接受一个回调函数作为prop。

目标

当用户在 InputField 中输入内容并提交表单时,将输入框的值 (inputVal) 传递给父组件。

PPT.AI
PPT.AI

AI PPT制作工具

下载

实现

  1. 定义 onSubmit prop: InputField 组件将通过props接收一个名为 onSubmit 的函数。
  2. 调用回调函数: 在 handleSubmit 函数中,获取到 inputVal 后,调用这个 onSubmit prop,并将 inputVal 作为参数传入。

代码示例

// components/InputField.js
import React from 'react';

export default function InputField({ onSubmit }) { // 接受 onSubmit prop
  function handleSubmit(e) {
    // 阻止浏览器默认的表单提交行为
    e.preventDefault();

    // 读取表单数据
    const form = e.target;
    const inputVal = form.myInput.value;

    console.log("Input value from child:", inputVal);

    // 调用父组件传入的回调函数,并传递输入值
    if (onSubmit) { // 确保 onSubmit 存在
      onSubmit(inputVal);
    }
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <input name="myInput" id="adress-field" placeholder="Enter adress" autoComplete="on" />
      <button type="submit" id="adress-button">Send</button>
    </form>
  );
}

解释

现在,InputField 不再直接处理 inputVal 的最终用途,而是将其职责委托给了父组件。它通过 onSubmit prop 提供了一个接口,父组件可以通过这个接口来“监听”子组件的提交事件并获取数据。

第二步:在父组件 App.js 中接收并处理数据

App 组件需要定义一个状态来存储从 InputField 接收到的数据,并使用 useEffect 钩子来监听这个状态的变化,从而触发API请求。

目标

  1. 在 App 组件中存储从 InputField 接收到的用户输入。
  2. 根据这个输入值动态地构建API请求URL。
  3. 当输入值变化时,重新发起API请求。

实现

  1. 定义状态: 使用 useState 在 App 组件中创建一个状态变量,例如 searchValue,用于存储从 InputField 接收到的值。
  2. 创建回调函数: 定义一个名为 handleSearchSubmit 的函数。这个函数将作为 InputField 的 onSubmit prop 传递,它接收 InputField 传递过来的值,并用这个值更新 searchValue 状态。
  3. 传递回调: 在 App 组件中渲染 InputField 时,将 handleSearchSubmit 作为 onSubmit prop 传递给它。
  4. 更新 useEffect: 修改 useEffect 钩子,使其依赖于 searchValue。当 searchValue 改变时,useEffect 会重新执行,触发新的 fetch 请求。同时,将API URL中的占位符替换为 searchValue。

代码示例

// App.js
import './App.css';
import AccountNumber from "./components/AccountNumber";
import InputField from "./components/InputField";
import { useEffect, useState } from "react";

function App() {
  // token fetch 相关状态
  const [tokens, setTokens] = useState([]);
  const [loading, setLoading] = useState(false);
  // 新增状态:用于存储从 InputField 接收到的搜索值
  const [searchValue, setSearchValue] = useState(null); 

  // 处理 InputField 提交的回调函数
  const handleSearchSubmit = (val) => {
    setSearchValue(val); // 更新 searchValue 状态
  };

  useEffect(() => {
    // 只有当 searchValue 有效时才执行 fetch 请求
    if (searchValue) { 
      setLoading(true);
      fetch(`https://api.multiversx.com/accounts/${searchValue}/tokens`) // 使用 searchValue 构建 URL
        .then(response => response.json())
        .then(json => setTokens(json))
        .finally(() => {
          setLoading(false);
        });
      console.log("Fetching tokens for:", searchValue); 
    } else {
      // 如果 searchValue 为空,可以清空 tokens 或显示提示
      setTokens([]); 
    }
  }, [searchValue]); // 将 searchValue 添加到依赖数组,当它变化时重新执行 useEffect

  // ... 其他辅助函数(round, numberWithSpaces)保持不变

  return (
    <content className="content">
        <div className="up-side">
            <div className="account-number-box">
                <p id="p-account-number">Total number of accounts</p>
                <p id="account-number"><AccountNumber/></p>
            </div>
            <div className="adress-search">
                {/* 正确地渲染 InputField 组件,并传递回调函数 */}
                <InputField onSubmit={handleSearchSubmit} /> 
            </div>
            {/* 可以显示当前的搜索值,例如: */}
            <p>Current Search Value: {searchValue || "None"}</p>
        </div>
        <div className="down-side">
            <table className="Token-section-output">
              {loading ? (
                <div>Loading...</div>
              ) : (
                <>
                  <h1>Tokens</h1>
                  {/* ... tokens 列表渲染逻辑 ... */}
                  <table className='Token-section-output' border={0}>
                    <tr className='token-row-type'>
                      <th className='token-column'>Name</th>
                      <th className='center-column'>Price</th>
                      <th>Hold</th>
                    </tr>
                    <tr className="space20"/>
                    {tokens.length > 0 ? (
                      tokens.map(token => (
                        <tr className='token-row' key={token.id}>
                          <td className='token-column'>
                          <img className="img-Tokens" src = {token?.assets?.pngUrl ?? "img/Question.png"} /> 
                            <p>{token.name}</p> 
                          </td>
                          <td className='center-column'> <p>${round(token.price, 10000000)}</p> </td>
                          <td> 
                            <p>{round(token.balance / Math.pow(10, token.decimals), 10000000)}</p> 
                            <p className='token-hold'>${round(token.valueUsd, 10000000)}</p>
                          </td>
                        </tr>
                      ))
                    ) : (
                      <tr><td colSpan="3">No tokens found or no search value provided.</td></tr>
                    )}
                  </table>
                </>
              )}
            </table>
        </div>   
    </content>
  );
}

export default App;

解释

  • searchValue 状态: App 组件现在拥有了一个 searchValue 状态,它会在 InputField 提交时被更新。
  • handleSearchSubmit 回调: 这个函数充当了 InputField 和 App 之间的桥梁。当 InputField 调用 onSubmit 时,实际上是在调用 App 组件中定义的 handleSearchSubmit,从而更新 App 的状态。
  • useEffect 依赖: useEffect 的依赖数组中包含了 searchValue。这意味着每当 searchValue 发生变化时(即用户提交了新的输入),useEffect 内部的副作用函数就会重新执行,触发新的API请求。
  • 条件 fetch: if (searchValue) 判断确保只有当 searchValue 有实际值时才发起网络请求,避免在组件初次渲染或 searchValue 为空时发出无效请求。
  • 组件渲染方式: 注意 InputField 组件现在是使用 JSX 语法 <InputField onSubmit={handleSearchSubmit} /> 进行渲染的,而不是像函数一样直接调用 InputField()。这是React组件的正确使用方式,确保了组件的生命周期和状态管理机制正常工作。

注意事项与最佳实践

  1. 组件渲染方式: 务必使用 JSX 语法 <ComponentName /> 来渲染 React 组件。直接调用 ComponentName() 会将其作为普通 JavaScript 函数执行,导致组件无法拥有自己的状态、生命周期方法,并且可能导致性能问题或意外行为。
  2. useEffect 依赖数组: useEffect 的依赖数组是其核心。确保将所有在副作用函数内部使用到的、且可能随时间变化的外部变量(如 searchValue)都包含在依赖数组中。这可以避免闭包问题,并确保副作用在正确的时间点重新运行。
  3. 初始状态与条件请求: 在 useEffect 中发起网络请求时,通常需要考虑请求参数的初始状态。如果 searchValue 初始为 null 或空字符串,可能不希望立即发起请求。通过 if (searchValue) 这样的条件判断,可以有效控制请求的时机。
  4. 错误处理: 在实际应用中,fetch 请求应该包含 .catch() 块来处理网络错误、API响应错误或其他异常情况,以提升应用的健壮性。
  5. 加载状态: 使用 loading 状态来向用户提供视觉反馈,告知数据正在加载中,提升用户体验。

总结

通过本教程,我们学习了如何在React中有效地实现子组件向父组件传递数据,并利用这些数据驱动父组件的复杂逻辑,如动态API请求。核心思想是:父组件定义回调函数并作为props传递给子组件,子组件在特定事件发生时调用该回调函数并传入数据。父组件则利用 useState 管理接收到的数据,并结合 useEffect 钩子来响应数据变化,执行副作用(如网络请求)。掌握这一模式是构建复杂、交互式React应用的关键一步。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

254

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1089

2024.03.01

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

847

2023.08.22

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1567

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

650

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

1228

2024.03.22

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

25

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

CSS教程
CSS教程

共754课时 | 42.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号