You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React应用中如何将Home组件输入值传递给Main组件调用Pokemon API

解决方案:状态提升 + 回调函数传递

这是React开发中非常常见的跨组件状态通信问题,核心解法就是利用状态提升——把两个组件共享的状态放到它们的共同父组件中,再通过props传递数据和回调函数来实现数据流的流转。我给你拆解一下具体的实现步骤和代码示例:

1. 梳理组件结构,将共享状态提升到共同父组件

假设你的Home和Main组件都是App组件的子组件(如果不是,找到它们的共同祖先组件即可),我们把要用于API请求的宝可梦名称状态放到App里,这样两个子组件都能通过props访问或修改这个状态。

import { useState } from 'react';
import Home from './Home';
import Main from './Main';

function App() {
  // 共享的宝可梦名称状态,统一放在父组件维护
  const [pokemonName, setPokemonName] = useState('');

  // 定义接收输入值的回调函数,用于更新状态
  const handleSearchSubmit = (inputName) => {
    setPokemonName(inputName.trim());
  };

  return (
    <div className="app-container">
      {/* 把回调函数传给Home,用于提交时传递输入值 */}
      <Home onSearchSubmit={handleSearchSubmit} />
      {/* 把当前的宝可梦名称传给Main,作为API请求的参数 */}
      <Main targetPokemon={pokemonName} />
    </div>
  );
}

export default App;

2. 在Home组件中处理输入,提交时触发回调传递值

Home组件只需要负责维护输入框的局部状态,当用户点击提交按钮时,调用父组件传过来的回调函数,把输入值传递上去即可。

import { useState } from 'react';

function Home({ onSearchSubmit }) {
  // 局部状态,专门维护输入框的实时值
  const [inputValue, setInputValue] = useState('');

  const handleInputChange = (e) => {
    setInputValue(e.target.value);
  };

  const handleFormSubmit = (e) => {
    e.preventDefault();
    // 非空校验后,调用父组件的回调传递值
    if (inputValue.trim()) {
      onSearchSubmit(inputValue);
      // 提交后可以清空输入框,提升用户体验
      setInputValue('');
    }
  };

  return (
    <form className="search-form" onSubmit={handleFormSubmit}>
      <input
        type="text"
        value={inputValue}
        onChange={handleInputChange}
        placeholder="输入宝可梦名称搜索..."
      />
      <button type="submit">搜索</button>
    </form>
  );
}

export default Home;

3. Main组件监听状态变化,发起API请求

Main组件通过props接收父组件传来的宝可梦名称,使用useEffect监听这个值的变化,一旦值更新,就自动发起API请求获取详情。

import { useState, useEffect } from 'react';

function Main({ targetPokemon }) {
  const [pokemonData, setPokemonData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  // 监听targetPokemon的变化,触发API请求
  useEffect(() => {
    // 如果名称为空,不执行请求
    if (!targetPokemon) return;

    const fetchPokemonDetails = async () => {
      setLoading(true);
      setError(null);
      try {
        // 调用宝可梦API,注意转小写(API要求)
        const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${targetPokemon.toLowerCase()}`);
        if (!response.ok) throw new Error('找不到对应的宝可梦');
        const data = await response.json();
        setPokemonData(data);
      } catch (err) {
        setError(err.message);
        setPokemonData(null);
      } finally {
        setLoading(false);
      }
    };

    fetchPokemonDetails();
  }, [targetPokemon]); // 依赖项设置为targetPokemon,值变化时重新执行

  // 根据状态渲染不同内容
  if (loading) return <div className="loading">正在加载...</div>;
  if (error) return <div className="error">错误:{error}</div>;
  if (!pokemonData) return <div className="prompt">请输入宝可梦名称进行搜索</div>;

  // 渲染宝可梦详情
  return (
    <div className="pokemon-details">
      <h2>{pokemonData.name.charAt(0).toUpperCase() + pokemonData.name.slice(1)}</h2>
      <img src={pokemonData.sprites.front_default} alt={pokemonData.name} />
      <p>身高:{pokemonData.height / 10}m</p>
      <p>体重:{pokemonData.weight / 10}kg</p>
      <h3>属性:</h3>
      <ul>
        {pokemonData.types.map((typeItem, index) => (
          <li key={index}>{typeItem.type.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default Main;

核心逻辑说明

  • 状态提升:把原本要在Main中维护的宝可梦名称状态,提到了两个组件的共同父组件App里,符合React单向数据流的设计理念。
  • 回调传递:Home组件通过props接收父组件的回调函数,提交时将输入值“向上”传递给父组件更新状态。
  • 监听触发请求:Main组件通过useEffect监听props传来的名称变化,自动触发API请求,实现数据的自动更新。

如果你的项目后续复杂度提升,也可以考虑用Context API或者Redux之类的状态管理工具,但对于当前场景,状态提升是最轻便、易维护的方案。

内容的提问来源于stack exchange,提问作者Dax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:57:22