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

React父组件API数据传递给子组件Slide为空问题求助

问题描述

尝试将API数据放入轮播组件,父组件App已成功获取API数据并存入movieObj状态,但传递给子组件Slide后,子组件的slideObj始终是空数组,无法拿到更新后的数据。

App.js代码

import { Component } from 'react'
import Header from './components/Header'
import Slide from './components/Slide'
import Body from './components/Body'
import Footer from './components/Footer'
import './App.css'
import axios from 'axios'

export default class App extends Component {

  constructor(props){
    super(props);
    this.state={
      movieObj:[] //用于存储获取到的API数据的状态
    }
  }


  getMovies=async()=>{
    //箭头函数
      await axios({
      method:'get',
      url:'/v1/search/movie.json?query="스파이더맨"&display=6',
      dataType:'json',
      headers:{
        "X-Naver-Client-Id":'pcSk4iqo1SpsvR7nh1Ul',
        "X-Naver-Client-Secret":'g8wy7q0lQ7'
      }
    })
    .then(response => 
      {
        console.log(response);
        console.log(response.data.items);
        this.setState({
          movieObj:response.data.items
        })
      }
    )
  }

  componentDidMount(){
    this.getMovies()//调用
  }


  render() {
    console.log(this.state.movieObj)
    console.log(1)
    return (
      <div id="app">
        <Header></Header>
        <Slide  list={this.state.movieObj}></Slide>//将API数据传递给子组件Slide
        <Body></Body>
        <Footer></Footer>
      </div>
    )
  }
}

Slide.js代码

import {Component} from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import { Navigation, Pagination, Autoplay, A11y } from 'swiper';
import '../css/slide.css'


// 导入Swiper样式
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
import 'swiper/css/scrollbar';  

export default class Slide extends Component {
  constructor(props){
    super(props);
    this.state={
      slideObj:this.props.list//用于接收来自App.js的(this.props.list)的状态
    }
  }

  render() {
    console.log(this.state.slideObj)
    return (
        <Swiper id="slide"
            modules={[Navigation, Pagination, Autoplay, A11y]}
            spaceBetween={50}
            slidesPerView={4}
            loop= {true}
            //dir="ltr"//切换轮播前进方向.. 
            navigation// 上一页、下一页按钮
            autoplay={{delay: 2000, disableOnInteraction:false}}
            pagination={{ clickable: true }}
            onSlideChange={() => console.log('slide change')}
            onSwiper={(swiper) => console.log(swiper)}
            >
            <SwiperSlide className="item">
                <div id='movieInfo'>
                    Slide1
                </div>
            </SwiperSlide>
            <SwiperSlide className="item">Slide 2</SwiperSlide>
            <SwiperSlide className="item">Slide 3</SwiperSlide>
            <SwiperSlide className="item">Slide 4</SwiperSlide>
            <SwiperSlide className="item">Slide 5</SwiperSlide>
            <SwiperSlide className="item">Slide 6</SwiperSlide>
        </Swiper>
    )
  }
}
解决方案
  • 问题根源:子组件Slide的slideObj状态是在constructor中通过this.props.list初始化的,但constructor仅在组件挂载时执行一次。父组件的API数据是异步获取的,组件挂载时props.list还是空数组,后续父组件更新movieObj并传递新的props给子组件时,子组件的state不会自动同步更新。

  • 解决方法1:直接使用props,不存子组件state
    子组件不需要将props存入自身state,直接在render中使用this.props.list即可,这样能实时获取父组件传递的最新数据,同时简化代码:

    export default class Slide extends Component {
      render() {
        console.log(this.props.list)
        return (
            <Swiper id="slide"
                modules={[Navigation, Pagination, Autoplay, A11y]}
                spaceBetween={50}
                slidesPerView={4}
                loop= {true}
                navigation
                autoplay={{delay: 2000, disableOnInteraction:false}}
                pagination={{ clickable: true }}
                onSlideChange={() => console.log('slide change')}
                onSwiper={(swiper) => console.log(swiper)}
                >
                {/* 遍历API数据生成轮播项 */}
                {this.props.list.map((movie, index) => (
                  <SwiperSlide key={index} className="item">
                    <div id='movieInfo'>
                      <img src={movie.image} alt={movie.title.replace(/<\/?b>/g, '')} />
                      <p>{movie.title.replace(/<\/?b>/g, '')}</p>
                    </div>
                  </SwiperSlide>
                ))}
            </Swiper>
        )
      }
    }
    
  • 解决方法2:监听props变化更新子组件state
    如果必须将props存入子组件state,需要在componentDidUpdate生命周期中监听props的变化,更新state:

    export default class Slide extends Component {
      constructor(props){
        super(props);
        this.state={
          slideObj:this.props.list
        }
      }
    
      componentDidUpdate(prevProps) {
        // 当props.list变化时,同步更新state
        if (prevProps.list !== this.props.list) {
          this.setState({
            slideObj: this.props.list
          });
        }
      }
    
      render() {
        console.log(this.state.slideObj)
        return (
            <Swiper id="slide"
                modules={[Navigation, Pagination, Autoplay, A11y]}
                spaceBetween={50}
                slidesPerView={4}
                loop= {true}
                navigation
                autoplay={{delay: 2000, disableOnInteraction:false}}
                pagination={{ clickable: true }}
                onSlideChange={() => console.log('slide change')}
                onSwiper={(swiper) => console.log(swiper)}
                >
                {this.state.slideObj.map((movie, index) => (
                  <SwiperSlide key={index} className="item">
                    <div id='movieInfo'>
                      <img src={movie.image} alt={movie.title.replace(/<\/?b>/g, '')} />
                      <p>{movie.title.replace(/<\/?b>/g, '')}</p>
                    </div>
                  </SwiperSlide>
                ))}
            </Swiper>
        )
      }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:05:28