点击Update按钮无法更新React父组件setApiData状态的问题
问题解决方法
核心问题
你的CustomComponent点击Update按钮时,只更新了自身的data状态,却没调用传入的onChange回调把新值传给父组件CallingComponent,导致父组件的setApiData完全没触发。另外还有两处细节问题需要修正:
具体修改步骤
让CustomComponent通知父组件更新
在handleUpdate函数里,拿到编辑器内容后,除了更新自身状态,还要调用onChange把内容传递给父组件:const handleUpdate = () => { if (editorRef.current) { const content = editorRef.current.getValue(); setData(content); // 新增:调用onChange把内容传给父组件 onChange?.(content); } };修正父组件的参数类型匹配问题
CustomComponent的onChange传递的是字符串,父组件里不需要额外调用toString(),直接使用参数即可,同时建议修正状态变量的命名(getApiData是状态值不是函数,不符合React useState的命名习惯):export const CallingComponent = () => { const [apiData, setApiData] = useState(''); // 假设初始值从API获取,示例用空字符串 return ( <CustomComponent defaultValue={apiData} onChange={(value: string) => setApiData(value)} /> ); };修复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
相关产品推荐
相关产品推荐

