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

SolidJS自定义Hook获取API数据异常:组件接收空值问题排查

SolidJS自定义Hook获取API数据返回空值的问题

问题描述

刚接触SolidJS,编写自定义Hook获取API响应数据并传递给组件,但调用该Hook时组件得到的是空值。Hook内的console.log(data())能正常输出数据,但组件内的console.log(data)显示null或空值。

Hook代码

import { createEffect, createSignal } from "solid-js";
import axios from "axios";

function useFetch(url){

    const [data,signalData] = createSignal(null)

    createEffect(() =>
    {
        axios.get(url).then((response) => 
            
            {signalData(response.data.data)
                console.log(data())
            }

        ).catch(err =>console.log(err))
    },[url])

    return data();
}
export default useFetch;

组件调用代码

function Club_window(){

    
    const data = useFetch('http://localhost:8080/team?team_id=151')
    console.log(data)

    return(

    <div class={main_menu_clubCSS.club_window}>
    <div class={main_menu_clubCSS.img_wrapper}>
        <img class={main_menu_clubCSS.img_blur} src='https://cdn.footystats.org/img/teams/england-liverpool-fc.png'/>
        <div class={main_menu_clubCSS.club_content}>
                <p><span>BIGGER CLUB</span><span>Test</span></p>
        </div>
    </div>
</div>
)}
export default Club_window;

错误原因

  1. 返回静态值而非响应式信号:Hook里返回data(),这是信号的初始静态值null,后续API请求完成后信号更新,组件无法感知到变化,因为拿到的只是一个固定值,不是响应式信号本身。
  2. 组件未订阅信号更新:组件获取的是初始null后,没有机制跟踪信号的后续变化,所以即使Hook内更新了数据,组件也不会重新渲染获取新值。

解决方案

修正后的Hook代码

import { createEffect, createSignal } from "solid-js";
import axios from "axios";

function useFetch(url){
    const [data, signalData] = createSignal(null)

    // SolidJS会自动跟踪effect内的响应式依赖,无需手动传依赖数组
    createEffect(() => {
        // 保存当前url,避免异步请求完成时url已变化导致的竞态问题
        const currentUrl = url;
        axios.get(currentUrl)
            .then((response) => {
                if (currentUrl === url) {
                    signalData(response.data.data);
                }
            })
            .catch(err => console.log(err))
    });

    // 返回信号函数本身,而非调用后的静态值
    return data;
}
export default useFetch;

修正后的组件调用代码

function Club_window(){
    // 获取响应式信号
    const data = useFetch('http://localhost:8080/team?team_id=151')

    // 在响应式上下文中监听数据变化
    createEffect(() => {
        console.log("最新数据:", data());
    });

    return(
        <div class={main_menu_clubCSS.club_window}>
            <div class={main_menu_clubCSS.img_wrapper}>
                <img class={main_menu_clubCSS.img_blur} src='https://cdn.footystats.org/img/teams/england-liverpool-fc.png'/>
                <div class={main_menu_clubCSS.club_content}>
                    {/* JSX中调用data()获取值,SolidJS会自动跟踪变化并重新渲染 */}
                    <p><span>BIGGER CLUB</span><span>{data() ? data().teamName : '加载中...'}</span></p>
                </div>
            </div>
        </div>
    )
}
export default Club_window;

关键说明

  • 返回信号而非静态值:只有返回信号函数,组件才能通过调用data()获取最新值,并且在信号更新时触发组件重新渲染。
  • 自动依赖跟踪:SolidJS的createEffect会自动识别内部访问的响应式值(比如url),当url变化时自动重新执行请求,无需手动维护依赖数组。
  • 处理竞态问题:保存当前请求的url,确保只有当请求的url与当前url一致时才更新数据,避免多个请求同时触发时的结果覆盖问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:12:41