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

React中如何从一个组件的函数更新另一个组件的数组状态

解决思路

你当前渲染电影列表的movies状态存放在父组件App中,搜索逻辑在子组件Topnav内,只需要把App中修改movies状态的方法通过props传递给Topnav,搜索拿到结果后调用该方法更新状态即可自动刷新列表。


第一步:修改App.js

  1. 给Topnav组件传递修改movies状态的方法
  2. 把初始请求的API_URL导出给Topnav使用,用于清空搜索词时回到默认热门列表

修改后的App.js代码:

import React, { useEffect, useState } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Movies from './components/Movies';
import Topnav from './components/Topnav';
import './App.css';
import './components/Movies.css';

export const API_KEY = 'api_key=247b6aa143f3f2c0b100c0cbdfb1ac99';
export const BASE_URL = 'https://api.themoviedb.org/3';
export const API_URL = BASE_URL + '/discover/movie?sort_by=popularity.desc&' + API_KEY;
export const IMG_URL = 'https://image.tmdb.org/t/p/w500';
export const searchURL = BASE_URL + '/search/movie?'+ API_KEY;

function App() {
  const [movies, setMovies] = useState ([]);

  useEffect(() => {
    fetch (API_URL)
      .then(res => res.json())
      .then(data => {
        console.log(data);
        setMovies(data.results);
      });
  }, [])

  return (
    <>
        <Router>
          {/* 传递setMovies方法给子组件 */}
          <Topnav updateMovies={setMovies} />
          <div className="movie-container">
            {movies.length > 0 && 
              movies.map((movie) => (
                <Movies key={movie.id} {...movie} />))}
          </div>
          <Routes>
            <Route exact path='/' />
          </Routes>
        </Router>
    </>
  );
}

export default App;

第二步:修改Topnav.js

  1. 接收父组件传递的updateMovies方法
  2. 搜索拿到结果后调用该方法更新全局电影列表
  3. 补充清空搜索词时回到默认热门列表的逻辑

修改后的Topnav核心代码:

import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import './Topnav.css';
// 导入初始API_URL
import { searchURL, API_URL } from '../App';

// 接收父组件传的updateMovies
function Topnav({ updateMovies }) {
    const [click, setClick] = useState(false)
    const handleClick = () => setClick(!click)

    const modeToggle = () => {
        document.body.classList.toggle('dark')
    }

    const [query, setQuery] = useState("")

    const onChange = (e) => {
        e.preventDefault();
        const searchVal = e.target.value
        setQuery(searchVal)
        // 搜索词为空时拉取默认热门列表
        if(!searchVal.trim()) {
            fetch(API_URL)
            .then(res => res.json())
            .then(data => {
                if(data.results) {
                    updateMovies(data.results)
                }
            })
            return
        }
        // 非空时走搜索接口
        fetch(searchURL+`&language=en-US&page=1&include_adult=false&query=${searchVal}`)
        .then((res) => res.json())
        .then((data) => {
            console.log(data.results);
            if(data.results) {
                // 更新父组件的电影列表
                updateMovies(data.results)
            }
        })
    }

    // 后面的return部分代码不用改,保持原样即可
    return (
        <>
        <nav className="topnav">
            <div className="topnav-container">
                <Link to='/' className='topnav-logo'>
                    <img src={require('../img/logo.png').default} alt="logo" />
                </Link>
                <div className="wrapper">
                    <form id='search-bar'>
                        <input
                        type="text"
                        placeholder="Search"
                        className="search"
                        id="search"
                        value={query}
                        onChange={onChange}
                        />
                    </form>
                    <label className="switch">
                        <input type="checkbox" id="mode-toggle" onChange={modeToggle}/>
                    </label>
                </div>
            </div>
        </nav>
        </>
    )
}

export default Topnav

可选优化

  • 加防抖处理:避免每次输入字符都触发接口请求,可设置300ms延迟再发起请求,减少服务器压力
  • 新增加载状态、空结果提示,优化用户体验
  • 补充接口请求错误的兜底处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:54:09