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

Svelte组件报错:无法读取null的current属性及unsubscribe不是函数

问题分析与修复方案

错误原因

  1. "TypeError: unsubscribe is not a function":在subscribe回调中直接调用unsubscribe()时,unsubscribe变量还未完成赋值——subscribe会立即执行回调,此时变量还没拿到返回的取消订阅函数。
  2. "Cannot read properties of null (reading 'current')":你的loading判断仅检查value !== undefined,但如果store返回的value是null或不含current属性的对象,loading会被设为false,渲染时访问$currentOneCallData.current就会触发读取null属性的错误。

修复方案(推荐:自动订阅)

移除手动订阅逻辑,改用Svelte原生的$语法自动监听store变化,Svelte会自动处理订阅与取消订阅,完全避免手动管理的错误。同时优化loading的判断逻辑,确保数据真正可用后再渲染。

修复后完整代码

<script>
  import rain from "../assets/icons/d-rain.png";
  import { currentOneCallData } from "../cli";

  // 响应式判断:仅当store数据存在且包含current属性时,才结束loading
  $: loading = !($currentOneCallData?.current !== undefined);

  function convertUnixTimestamp(timestamp) {
    const months = [
      "Jan", "Feb", "Mar", "Apr", "May", "Jun",
      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
    ];
    const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

    const date = new Date(timestamp * 1000);
    const day = days[date.getDay()];
    const month = months[date.getMonth()];
    const dayOfMonth = date.getDate();

    return `${day}, ${month} ${dayOfMonth}`;
  }
</script>

{#if !loading}
  <div class="current-container">
    <div class="text-content">
      <div class="dateAndTime">
        <p class="date">{convertUnixTimestamp($currentOneCallData.current.dt)}</p>
        <p class="time">7:40 AM</p>
      </div>
      <p class="temp">{$currentOneCallData.current.temp}<sup class="temp-unit">°C</sup></p>
      <h4 class="feel-container">
        Feels like <span class="feel">{$currentOneCallData.current.feels_like} <span class="temp-unit">°C</span></span>
      </h4>
      <h3 class="desc">{$currentOneCallData.current.weather[0].description}</h3>
    </div>
    <div class="icon-container">
      <img src={rain} alt="Rain icon" class="icon" />
    </div>
  </div>
{:else}
  <div class="loading"><p>Loading...</p></div>
{/if}

关键修复点

  • 用$: loading = !($currentOneCallData?.current !== undefined)实现响应式判断:当store数据变化时,自动检查是否存在有效的current属性,确保数据可用后才结束loading。
  • 移除了onMount、onDestroy中的手动订阅逻辑,无需再处理unsubscribe,Svelte会在组件销毁时自动取消订阅,彻底解决unsubscribe is not a function错误。
  • 给img标签补充了有意义的alt文本,提升页面可访问性。

备选方案(保留手动订阅)

如果必须保留手动订阅模式,需要修复unsubscribe未赋值的问题,并优化数据判断逻辑:

<script>
  import { onDestroy, onMount } from "svelte";
  import rain from "../assets/icons/d-rain.png";
  import { currentOneCallData } from "../cli";

  let unsubscribe;
  let loading = true;

  onMount(() => {
    let isUnsubscribed = false;
    // 先保存订阅返回的取消函数
    const unsubscribeFunc = currentOneCallData.subscribe(value => {
      if (!isUnsubscribed && value?.current !== undefined) {
        loading = false;
        unsubscribeFunc();
        isUnsubscribed = true;
      }
    });
    unsubscribe = unsubscribeFunc;
  })

  onDestroy(() => {
    if (unsubscribe) {
      unsubscribe(); 
    }
  });

  // convertUnixTimestamp函数保持不变
</script>

<!-- 模板部分保持不变 -->

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 15:07:32