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

React中子组件调用completeCard时如何向父组件传值更新completedChallenges状态

实现方案

核心思路是父组件向子组件传递回调函数,子组件完成任务逻辑后调用该回调,把完成的卡片ID回传给父组件更新状态。

步骤1:修改父组件Dashboard

  • 新增处理挑战完成的回调函数,接收cardID参数更新completedChallenges状态,同时刷新展示的卡片列表
  • 渲染Card组件时将回调函数作为prop传递给子组件
  • 优化原有异步逻辑的潜在问题:setUID是异步操作,调用setPage时直接取auth.currentUser.uid避免拿到旧值

修改后的父组件完整代码:

import React, { useState, useEffect } from 'react';
import { auth, database } from '../../utils/firebase';
import { ref, get} from "firebase/database";
import { Redirect } from 'react-router-dom';
import { onAuthStateChanged } from "firebase/auth";

//Components
import Navbar from './Navbar';
import ProgressBar from './ProgressBar';
import Card from './Card';

function Dashboard() {
    const [uid, setUID] = useState("");
    const [completedChallenges, setCompletedChallenges] = useState([]);
    const [displayCards, setDisplayCard] = useState([]);

    // 新增:处理挑战完成的回调函数
    const handleChallengeComplete = (finishedCardID) => {
        // 不可变方式更新已完成挑战列表
        setCompletedChallenges(prev => [...prev, finishedCardID]);
        // 刷新卡片展示,过滤掉已完成的卡片
        setCards();
    }

    function setCards() {
      const userRef = ref(database, 'challenges');
          get(userRef).then((snapshot) => {
            const data = snapshot.val();
            var currentDisplayCards = [];
            for(let i =1; i <= 10; i++){
              if(currentDisplayCards.length == 5) {break;}
              if(completedChallenges.indexOf(parseInt(i)) == -1){
                currentDisplayCards.push(data[i]);
              }
            }
            setDisplayCard(currentDisplayCards);
          });
    }

    function setPage() {
          const currentUid = auth.currentUser.uid;
          setUID(currentUid);
          const userRef = ref(database, 'users/' + currentUid);
          get(userRef).then((snapshot) => {
            const data = snapshot.val();
            setCompletedChallenges(data["challenges"]);
            setCards();
          });
    }

    useEffect(() => {
      onAuthStateChanged(auth, (user) => {
        if (user) {
          setPage();
        } else {
          return <Redirect to= '/'/>
        }
      });
    }, []); // 移除uid依赖,onAuthStateChanged只会在auth状态变化时触发
    
    return (
        <div>
            <Navbar/>
            <h2> Your missions </h2>
            {displayCards.map((card) => (
              <Card 
              uid={uid} 
              key={card.key} 
              cardID={card.key} 
              name={card.name} 
              description={card.description}
              // 传递回调给子组件
              onComplete={handleChallengeComplete}
              />
            ))}
        </div>
    );
}

export default Dashboard;

步骤2:修改子组件Card

  • 移除冗余的uid本地状态,直接使用props传递的uid即可
  • 在completeCard的firebase更新操作成功后,调用父组件传递的onComplete回调,把当前卡片ID回传
  • 补充update操作的错误捕获,避免异常无提示

修改后的子组件完整代码:

import React from 'react';
import { ref, update, get} from "firebase/database";
import { database } from '../../utils/firebase';
import './Card.css';

function Card(props) {
    function completeCard() {
        const userRef = ref(database, 'users/' + props.uid);
          get(userRef).then((snapshot) => {
            const data = snapshot.val();
            const completedMissions = data["challenges"];
            completedMissions.push(props.cardID);
            const updates = {};
            updates['/users/' + props.uid +'/challenges'] = completedMissions;
            // firebase更新成功后调用父组件回调
            update(ref(database), updates).then(() => {
                props.onComplete(props.cardID);
            }).catch(err => {
                console.error("更新挑战状态失败:", err);
            });
          });
          
    }
    return(
        <div className="card">
            <h1>{props.name}</h1>
            <p>{props.description}</p>
            <button onClick={completeCard}>Completar</button>
            <button>+Info</button>
        </div>
    )
}
export default Card;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 21:48:01