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

点击Update按钮无法更新React父组件setApiData状态的问题

问题解决方法

核心问题

你的CustomComponent点击Update按钮时,只更新了自身的data状态,却没调用传入的onChange回调把新值传给父组件CallingComponent,导致父组件的setApiData完全没触发。另外还有两处细节问题需要修正:

具体修改步骤

  1. 让CustomComponent通知父组件更新
    在handleUpdate函数里,拿到编辑器内容后,除了更新自身状态,还要调用onChange把内容传递给父组件:

    const handleUpdate = () => {
      if (editorRef.current) {
        const content = editorRef.current.getValue();
        setData(content);
        // 新增:调用onChange把内容传给父组件
        onChange?.(content);
      }
    };
    
  2. 修正父组件的参数类型匹配问题
    CustomComponent的onChange传递的是字符串,父组件里不需要额外调用toString(),直接使用参数即可,同时建议修正状态变量的命名(getApiData是状态值不是函数,不符合React useState的命名习惯):

    export const CallingComponent = () => {
      const [apiData, setApiData] = useState(''); // 假设初始值从API获取,示例用空字符串
      return (
        <CustomComponent
          defaultValue={apiData}
          onChange={(value: string) => setApiData(value)}
        />
      );
    };
    
  3. 修复CustomComponent的无限重渲染隐患
    直接在组件顶层写if (initialDefault != defaultValue)会触发频繁的状态更新,进而导致无限重渲染,换成useEffect监听defaultValue的变化更安全:

    useEffect(() => {
      if (defaultValue !== initialDefault) {
        setInitialDefault(defaultValue);
        setData(defaultValue);
      }
    }, [defaultValue, initialDefault]);
    

    记得导入useEffect:import { useState, useRef, useEffect } from 'react';

完整修改后的CustomComponent代码

import { useState, useRef, useEffect } from 'react';

interface CustomComponentProp {
  onChange?: (value: string) => void;
  defaultValue?: string;
}

export const CustomComponent = ({ defaultValue, onChange }: CustomComponentProp) => {
  const [value, setValue] = useState("");
  const editorRef = useRef<any>(null); // 初始值用null比[]更合理
  const [data, setData] = useState(defaultValue);
  const [initialDefault, setInitialDefault] = useState(defaultValue);

  useEffect(() => {
    if (defaultValue !== initialDefault) {
      setInitialDefault(defaultValue);
      setData(defaultValue);
    }
  }, [defaultValue, initialDefault]);

  const handleEditorDidMount = (editor: any) => {
    editorRef.current = editor;
    editor.focus();
  };

  function handleRemove() {
    setData("");
    setValue("");
    // 移除时也可以通知父组件清空状态
    onChange?.("");
  }

  const handleUpdate = () => {
    if (editorRef.current) {
      const content = editorRef.current.getValue();
      setData(content);
      onChange?.(content);
    }
  };

  return (
    <Settings>
      <SettingsSection>
        <Editor
          theme="vs-light"
          language="scss"
          value={data}
          onMount={handleEditorDidMount}
          onChange={(value) => setValue(value as string)}
        />
        <Button variant="outline" onPress={handleUpdate}>
          Update
        </Button>
        <Button variant="outline" onPress={handleRemove}>
          Remove
        </Button>
      </SettingsSection>
    </Settings>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 18:50:17