React中如何传递API调用结果至其他组件并触发渲染?
React中跨组件传递API数据并触发条件渲染的实现方法
针对你的需求,核心思路是利用React的单向数据流,把API获取的状态提升到两个组件的共同父组件中,再通过props把数据传递给需要渲染GLTF的Canvas组件,具体步骤如下:
1. 修改WeatherLogic组件,让它能把数据传递给父组件
原来的WeatherLogic自己管理状态,现在添加一个回调props,当API获取到数据后,把weatherDescript传递给父组件:
import { useEffect, useState } from "react"; export default function WeatherLogic({ onWeatherChange }) { const [userLocation, setUserLocation] = useState(""); const [temperature, setTemp] = useState(""); const [weatherDescript, setWeatherDescript] = useState(""); const handleInput = (event) => { setUserLocation(event.target.value); }; const getWeather = async (userLocation) => { if (!userLocation) return; // 避免空值调用API const apiKey = import.meta.env.VITE_APP_API_KEY; const res = await fetch( `https://api.openweathermap.org/data/2.5/weather?q=${userLocation}&appid=${apiKey}&units=metric` ); const data = await res.json(); setTemp(data.main.temp); setWeatherDescript(data.weather[0].description); // 调用父组件传过来的回调,把数据传出去 onWeatherChange({ temperature: data.main.temp, weatherDescript: data.weather[0].description, location: userLocation }); }; useEffect(() => { getWeather(userLocation); }, [userLocation]); return ( <div className="formcontainerparent"> <div className="formcontainerchild"> <form className="weatherform"> <label>Location <input type="text" name="name" value={userLocation} onChange={handleInput} /> </label> </form> <h1>{userLocation}</h1> <h2>{temperature}°C</h2> <h3>{weatherDescript}</h3> </div> </div> ); }
2. 创建父组件(比如App),管理共享状态并传递给子组件
父组件保存从WeatherLogic传来的天气数据,再把weatherDescript传递给负责渲染GLTF的CanvasComponent:
import { useState } from "react"; import WeatherLogic from "./WeatherLogic"; import CanvasComponent from "./CanvasComponent"; export default function App() { const [weatherData, setWeatherData] = useState({ weatherDescript: "" }); // 接收WeatherLogic传递过来的数据 const handleWeatherChange = (data) => { setWeatherData(data); }; return ( <div className="app-container"> <WeatherLogic onWeatherChange={handleWeatherChange} /> {/* 把weatherDescript传给Canvas组件 */} <CanvasComponent weatherDescript={weatherData.weatherDescript} /> </div> ); }
3. 实现CanvasComponent,根据weatherDescript条件渲染GLTF
在这个组件里,通过props拿到weatherDescript,用判断语句渲染对应的GLTF模型:
import { Canvas } from '@react-three/fiber'; import { useLoader } from '@react-three/fiber'; import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; export default function CanvasComponent({ weatherDescript }) { // 加载不同的GLTF模型 const sunnyModel = useLoader(GLTFLoader, '/models/sunny.gltf'); const rainyModel = useLoader(GLTFLoader, '/models/rainy.gltf'); const cloudyModel = useLoader(GLTFLoader, '/models/cloudy.gltf'); let currentModel; // 根据天气描述判断渲染哪个模型 if (weatherDescript.includes('sun') || weatherDescript.includes('clear')) { currentModel = sunnyModel; } else if (weatherDescript.includes('rain')) { currentModel = rainyModel; } else if (weatherDescript.includes('cloud')) { currentModel = cloudyModel; } return ( <Canvas> <ambientLight /> <pointLight position={[10, 10, 10]} /> {currentModel && <primitive object={currentModel.scene} scale={1} />} </Canvas> ); }
关键说明
- React状态是单向流动的,子组件之间不能直接传递数据,必须通过共同的父组件中转。
- 当
WeatherLogic中的weatherDescript更新时,会触发父组件状态更新,父组件再把新数据传给CanvasComponent,从而触发Canvas组件的重新渲染。 - 可根据OpenWeatherMap返回的实际天气描述文本,调整判断条件以匹配需求。
内容的提问来源于stack exchange,提问作者Katie
相关产品推荐
相关产品推荐

