React中如何通过Home页面传递props设置Fetch数据的键?
问题描述
我想在Home.jsx页面中为Fetch获取的数据设置对应的键,目前通过<Counter img='counter'/>传递props,但在Counter组件中使用data.props.img时出现错误:Counter.js:24 Uncaught TypeError: Cannot read properties of undefined (reading 'img'),直接使用data.counter则能正常运行,请问问题出在哪里?
相关代码
API代码
<?php $images = [ "logo" => "http://www.cbp-exercises.test/cowboy_cafe_react/cowboy-coffee-shop/src/api/img/logo.svg", "counter" => "http://www.cbp-exercises.test/cowboy_cafe_react/cowboy-coffee-shop/src/api/img/counter.jpg", ]; echo json_encode($images);
Home.jsx
import React from 'react'; import Counter from '../components/Home/Counter'; import "../style/Home.scss" function Home() { return ( <section class="main"> <div class="main_title"> <h1>Generic Hipster Coffee</h1> <h2>Specialty coffee, fresh food & local community.</h2> </div> <Counter img = 'counter'/> {/* 这里我想为数据设置对应的键 */} </section> ); } export default Home;
Counter.js
import { useState } from "react" import { useEffect } from "react" const Counter = (props) => { const [data, setData] = useState(null) const [dataLoaded, setDataLoaded] = useState(false) const loadData = async () => { const response = await fetch( "http://www.cbp-exercises.test/cowboy_cafe_react/cowboy-coffee-shop/src/api/images.php" ) const data = await response.json() console.log(data) setData(data) setDataLoaded(true) } useEffect(() => { loadData() }, []) return ( <div class='main_img'> {dataLoaded ? ( <> <img src={data.props.img} alt='counter' /> {/* 这里应该使用我的props */} </> ) : ( <p>We will have data here... later</p> )} </div> ) } export default Counter
问题分析与修复
核心问题
你混淆了组件接收的props和Fetch返回的data对象的关系:
props是父组件(Home.jsx)传递给Counter的独立参数,存在于Counter组件的props变量中,和fetch回来的data没有任何嵌套关系。- 从API获取的
data是一个普通对象,结构为{logo: "图片地址", counter: "图片地址"},它内部根本不存在props属性,所以data.props会返回undefined,自然无法读取img属性,触发报错。
修复代码
你需要用父组件传递的props.img作为键,去访问data对象中对应的属性,也就是使用方括号语法data[props.img]:
修改Counter.js中的img标签部分:
<img src={data[props.img]} alt='counter' />
额外优化建议
- React组件中需要把
class替换为className,避免和JavaScript的class关键字冲突,比如:
<section className="main"> <div className="main_title"> <div className='main_img'>
- 可以去掉冗余的
dataLoaded状态,直接通过data是否为null来判断数据是否加载完成:
const Counter = (props) => { const [data, setData] = useState(null) const loadData = async () => { const response = await fetch( "http://www.cbp-exercises.test/cowboy_cafe_react/cowboy-coffee-shop/src/api/images.php" ) const resData = await response.json() setData(resData) } useEffect(() => { loadData() }, []) return ( <div className='main_img'> {data ? ( <img src={data[props.img]} alt={props.img} /> ) : ( <p>We will have data here... later</p> )} </div> ) }
内容的提问来源于stack exchange,提问作者M. Khromov
相关产品推荐
相关产品推荐

