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

JSX点击事件多函数调用问题:loadData需二次点击生效

问题原因

React的useState更新是异步批量处理的,saveData中调用setSavedImageData(dataURL)后,savedImageData不会立刻更新。当multiFunc里紧接着执行loadData时,读取的还是更新前的null值,导致第一次点击无效果;第二次点击时savedImageData已完成更新,才能正常执行。

解决方案

方案一:直接传递数据(推荐)

既然saveData里已经生成了dataURL,直接把这个值传给loadData,跳过对savedImageData state的依赖:

const [savedImageData, setSavedImageData] = useState(null);

const saveData = async () => {
  if (canvasRef.current) {
    const canvas = canvasRef.current;
    const dataURL = canvas.toDataURL();
    
    setSavedImageData(dataURL);
    setStore(prevStore => [...prevStore, dataURL]);
    console.log(dataURL);
    console.log('data saved');
    return dataURL; // 返回生成的dataURL
  }
  return null;
};

const clearData = () => {
  const canvas = canvasRef.current
  const context = canvas.getContext('2d');
  context.clearRect(0, 0, canvas.width, canvas.height);
  console.log('data cleared ')
  return true 
};

const loadData = (data) => { // 接收传入的数据
  if (data) {
    setImageUrl(data);
    console.log(data)
    setIsRetrieveData(true);
    setIsDrawing(false);
    console.log('data loaded ')
  }
};

const multiFunc = async () => {
  const dataURL = await saveData(); // 等待saveData返回结果
  clearData();
  loadData(dataURL); // 直接传递数据给loadData
};

方案二:用useEffect监听state变化

如果必须依赖savedImageData的state更新,可以通过额外的触发状态,让useEffect在state更新后自动执行loadData:

const [savedImageData, setSavedImageData] = useState(null);
const [triggerLoad, setTriggerLoad] = useState(false);

// 监听savedImageData和triggerLoad的变化
useEffect(() => {
  if (triggerLoad && savedImageData) {
    loadData();
    setTriggerLoad(false); // 重置触发状态
  }
}, [savedImageData, triggerLoad]);

const saveData = async () => {
  if (canvasRef.current) {
    const canvas = canvasRef.current;
    const dataURL = canvas.toDataURL();
    
    setSavedImageData(dataURL);
    setStore(prevStore => [...prevStore, dataURL]);
    console.log(dataURL);
    console.log('data saved');
  }
};

const clearData = () => {
  const canvas = canvasRef.current
  const context = canvas.getContext('2d');
  context.clearRect(0, 0, canvas.width, canvas.height);
  console.log('data cleared ')
  return true 
};

const loadData = () => {
  if (savedImageData) {
    setImageUrl(savedImageData);
    console.log(savedImageData)
    setIsRetrieveData(true);
    setIsDrawing(false);
    console.log('data loaded ')
  }
};

const multiFunc = async () => {
  await saveData(); // 等待state更新进入队列
  clearData();
  setTriggerLoad(true); // 触发loadData执行
};
方案说明
  • 方案一逻辑更直接,完全避开了state异步更新的问题,性能更优,优先推荐。
  • 方案二更适合需要基于state更新联动其他复杂逻辑的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 21:22:51