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

使用craftjs的useNode时props为空:异步fetch赋值后仍无数据

问题分析与解决办法

1. 先搞清楚打印时机的问题

你在SocialMedia组件顶层写的console.log(props),会在组件每次渲染时执行。初始渲染时,props是你设置的默认值{socialLinks: {}},所以第一次打印肯定是空的。当异步请求完成调用setProp后,组件会重新渲染,这时候打印的props应该已经包含socialLinks了——你可能只是没注意到后续的打印记录。

可以改成带标识的打印,方便区分:

console.log("当前渲染的props:", props);

2. 修正函数声明的语法错误

你的getSocialMediaLinks函数在组件内部没加const声明,属于语法错误,会导致全局变量污染,直接改成:

const getSocialMediaLinks = async () => {
  // 原有逻辑
};

3. 给异步请求加日志验证数据

虽然你说单独测试请求正常,但在组件里还是要确认返回数据格式是否符合预期,避免拿到的response不是数组或者第一个元素为空:

const getSocialMediaLinks = async () => {
  try {
    const response = await fetchAPI("/social_medias", "GET");
    console.log("API返回结果:", response);
    if (!response?.length) {
      throw new Error("接口返回数据为空");
    }
    const { id, ...links } = response[0];
    console.log("提取的社交链接:", links);
    setProp((prevProps) => ({ ...prevProps, socialLinks: links }));
  } catch (err) {
    console.error("获取链接失败:", err);
  }
};

4. 直接订阅Craft.js节点的最新props

如果还是拿不到更新后的值,可以在SocialMedia组件里通过useNode直接订阅节点的props变化,确保拿到最新状态:

export const SocialMedia = ({ ...props }) => {
  const {
    connectors: { connect, drag },
    node: { data }
  } = useNode(node => ({
    data: node.data.props
  }));

  // 这里打印的是节点最新的props
  console.log("节点最新props:", data);

  return (
    <div {...props} ref={(ref) => connect(drag(ref))} className={classNames}>
      {/* 用data.socialLinks渲染你的链接 */}
      {Object.entries(data.socialLinks).map(([name, url]) => (
        <a key={name} href={url} target="_blank" rel="noopener noreferrer">
          {name}
        </a>
      ))}
    </div>
  );
};

完整修正后的代码

import { useEffect } from "react";
import { useNode } from "@craftjs/core";
import fetchAPI from "@utils/fetch/api";
import classNames from "classnames"; // 记得导入classNames

export const SocialMedia = ({ ...props }) => {
  const {
    connectors: { connect, drag },
    node: { data }
  } = useNode(node => ({
    data: node.data.props
  }));

  console.log("组件props:", props);
  console.log("节点最新props:", data);

  return (
    <div {...props} ref={(ref) => connect(drag(ref))} className={classNames}>
      {Object.entries(data.socialLinks).map(([key, url]) => (
        <a key={key} href={url} target="_blank" rel="noopener noreferrer">
          {key}
        </a>
      ))}
    </div>
  );
};

const SocialMediaSettings = () => {
  const {
    actions: { setProp },
  } = useNode((node) => ({
    setProp: node.setProp,
  }));

  const getSocialMediaLinks = async () => {
    try {
      const response = await fetchAPI("/social_medias", "GET");
      console.log("API返回:", response);
      if (!response?.length) {
        throw new Error("返回数据为空");
      }
      const { id, ...links } = response[0];
      console.log("提取的社交链接:", links);
      setProp((prevProps) => ({ ...prevProps, socialLinks: links }));
    } catch (err) {
      console.error("获取社交链接失败:", err);
    }
  };

  useEffect(() => {
    getSocialMediaLinks();
  }, []);

  return <>
      {/* 渲染你的设置面板 */}
   </>;
};

export const SocialMediaDefaultProps = {
  socialLinks: {},
};

SocialMedia.craft = {
  props: { ...SocialMediaDefaultProps },
  related: {
    settings: SocialMediaSettings,
  },
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:20:07