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

React使用useState钩子时如何在子组件中修改父组件的状态值

问题原因

你一共存在3处核心错误,共同导致了报错:

  1. 父组件给Form传setColors的方式错误
    你写的是<Form setColors={() => setColors()} />,相当于给子组件传了一个没有参数、调用时会直接执行空的setColors()的函数,这会直接把colors状态覆盖为undefined,数组没了自然调用map就报错。
  2. 子组件的颜色值校验逻辑完全错误
    你当前的校验条件color === /^#[0-9A-F]{6}$/i.test("#AABBCC")是把固定值#AABBCC传入正则校验,返回值永远是true,等于校验完全失效,没有起到过滤非法值的作用。
  3. 子组件往颜色数组中插入的值格式和父组件不统一
    父组件的colors数组存储的是不带#的十六进制颜色字符串,你在子组件中插入的是{color: 输入值}的对象,会导致后续渲染、拖拽逻辑全部异常。
修改方案

1. 修改父组件传参

把父组件中Form的调用部分改为直接传递setColors方法:

// 原来的错误写法
// <Form setColors={() => setColors()} />
// 修改为
<Form setColors={setColors} />

2. 修改Form组件的addColor逻辑

修正校验规则,同时统一插入值的格式:

function addColor() {
  const rawColor = colorRef.current.value.trim();
  // 空值直接提示
  if (!rawColor) {
    alert("请输入十六进制颜色值");
    colorRef.current.value = "";
    return;
  }
  // 兼容带#和不带#的输入
  const formatColor = rawColor.startsWith("#") ? rawColor.slice(1) : rawColor;
  // 校验是否是6位合法十六进制字符
  const isValid = /^[0-9A-F]{6}$/i.test(formatColor);
  if (!isValid) {
    alert("This color does not exist! Type a color hex that exists.");
    colorRef.current.value = "";
    return;
  }
  // 插入和原有格式一致的字符串,不要包裹对象
  setColors((prevColors) => {
    return [...prevColors, formatColor];
  });
  colorRef.current.value = "";
}

可选优化

可以把Form组件的键盘监听逻辑改成绑定在form的submit事件上,不需要全局绑定keydown事件,避免全局事件污染:
给form标签加onSubmit事件:

<form className="form" onSubmit={(e) => {e.preventDefault(); addColor();}}>

修改后就可以移除原来的useEffect全局键盘监听代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:24:05