使用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
相关产品推荐
相关产品推荐

