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;
错误原因
- 返回静态值而非响应式信号:Hook里返回
data(),这是信号的初始静态值null,后续API请求完成后信号更新,组件无法感知到变化,因为拿到的只是一个固定值,不是响应式信号本身。 - 组件未订阅信号更新:组件获取的是初始
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
相关产品推荐
相关产品推荐

