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

React父组件向子组件传递函数失效问题排查求助

React组件传参问题:点击盒子id消失且console.log显示undefined

我是React新手,正在学习基础在线教程。尝试将函数从父组件传递到子组件,但功能异常:点击盒子时console.log打印id为undefined,盒子内的id也会消失。请帮忙指出问题所在,谢谢!

代码片段

main.jsx

import React from "react";
import { useState } from "react";
import { Box } from "../boxes/box";
import "./main.css";
import boxData from "./../data/boxes-data.json";

export function Main() {

    const [boxes, setBoxes] = useState(boxData);

    function updateBox(boxId) {
        setBoxes((prevBoxes) => {
            return prevBoxes.map((box) => {
                console.log(box.id);
                return (box.id === boxId) ? { ...prevBoxes, on: !box.on } : box
            })
        });
    }

    return (
        <main className="main">
            <div className="container">
                <div className="row">
                    <div className="box--container">
                        {boxes.map((box, i) =>
                            <Box
                                key={i}
                                {...box}
                                handleUpdateBox={(event) => updateBox(box.id)}
                            />
                        )}
                    </div>
                </div>
            </div>
        </main>
    )
}

box.jsx

import React from "react";
import './box.css';
export function Box(props) {

    const styles = {
        backgoundColor: (props.on) ? "red" : "black"
    }

    return (
        <div
            style={styles}
            className="box"
            onClick={props.handleUpdateBox}
        >
            {props.id}
        </div>
    )
}

数据文件 boxes-data.json

[
    {
        "id": 1,
        "on": true
    },
    {
        "id": 2,
        "on": false
    },
    {
        "id": 3,
        "on": true
    },
    {
        "id": 4,
        "on": false
    },
    {
        "id": 5,
        "on": false
    },
    {
        "id": 6,
        "on": true
    }
]

问题原因及修复

  1. 状态更新时错误展开数组而非当前盒子对象
    在updateBox函数中,你写了{ ...prevBoxes, on: !box.on },这里prevBoxes是整个盒子数组,展开数组会把数组索引作为键名,完全覆盖原本的盒子对象,导致id等属性丢失。应该展开当前的box对象:
return box.id === boxId ? { ...box, on: !box.on } : box
  1. 样式属性拼写错误
    backgoundColor少了一个字母r,正确写法是backgroundColor,否则背景色样式不会生效。

  2. 建议用box.id作为key而非数组索引
    用数组索引当key,在元素顺序变化时可能引发渲染异常,直接用唯一的box.id作为key更稳妥:

<Box
    key={box.id}
    {...box}
    handleUpdateBox={() => updateBox(box.id)}
/>

修复后的updateBox函数:

function updateBox(boxId) {
    setBoxes((prevBoxes) => {
        return prevBoxes.map((box) => {
            return box.id === boxId ? { ...box, on: !box.on } : box
        })
    });
}

修复后的Box组件样式:

const styles = {
    backgroundColor: props.on ? "red" : "black"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:50:35