【问题标题】:What causes the "ctx[1] is not a function" error in this small Svelte app?是什么导致这个小型 Svelte 应用程序中出现“ctx[1] 不是函数”错误?
【发布时间】:2021-05-18 10:50:19
【问题描述】:

我正在使用 Svelte 开发一个小型待办事项应用程序。我列出了来自 jsonplaceholder 的 10 个待办事项。

我在 App.svelte 中有这个:

<script>
    import { onMount } from "svelte";
    import Header from './Header.svelte';
    import ToDoList from './ToDoList.svelte';
    import Footer from './Footer.svelte';
    const apiURL = "https://jsonplaceholder.typicode.com/todos";
    const limit = 10;
    let todos = [];
    export let unsolvedTodos = [];
    
    onMount(() => {
        getTodos();
    });
    
    const getTodos = () => {
        fetch(`${apiURL}?&_limit=${limit}`)
        .then(res => res.json())
        .then((data) => todos = data)
        .then(getUnsolvedTodos);
    }
    
    const getUnsolvedTodos = () => {
        unsolvedTodos = todos.filter(todo => {
            return todo.completed === false;
        })
    }

    const deleteTodo = (todo) => {
        let itemIdx = todos.findIndex(x => x == todo);
        todos.splice(itemIdx, 1);
        todos = todos;
  }
</script>

<div class="app-wrapper">
  <div id="toDoApp">
        <Header />
    <ToDoList todos={todos} />
    <Footer />
  </div>
</div>

在 ToDoList.app 中:

<script>
    import TodoItem from './TodoItem.svelte';
    export let todos;
    let deleteTodo;
</script>

{#if todos.length > 0}
  <ul class="todo-list">
    {#each todos as todo, index}
        <TodoItem {todo} on:deleteTodo = {deleteTodo(todo)} />
    {/each}
  </ul>
{/if}

在 TodoItem.svelte 中:

<script>
    import {createEventDispatcher} from 'svelte';
    import { fade, fly } from 'svelte/transition';
    import { flip } from 'svelte/animate';
    export let todo;
    
    const dispatch = createEventDispatcher();
    const Delete = () => dispatch("deleteTodo", todo);
</script>

<li transition:fly="{{x:-100, duration:200}}">
    <input type="checkbox" checked="{todo.completed}" />
    <span class="title {todo.completed ? 'done' : ''}">{todo.title}</span>
    <button on:click="{Delete}"><i class="fa fa-trash" aria-hidden="true"></i></button>
</li>

我一定是遗漏了一些东西,因为我收到了错误 ctx[1] is not a function,这可以在 REPL 中看到。

我做错了什么?

【问题讨论】:

    标签: javascript svelte


    【解决方案1】:

    ToDoList.svelte 中,您正在调用deleteTodo(todo),但deleteTodo 未定义。 Svelte 真的应该在这里抛出更好的错误信息......

    编辑:

    此外,如果您分配了一个事件处理程序,您希望传入对函数的引用,例如 on:deleteTodo = {() =&gt; deleteTodo(todo)}on:deleteTodo = {deleteTodo},而不是直接调用该函数。

    【讨论】:

    • 我在 ToDoList.svelte 的顶部有 let deleteTodo。我也有&lt;TodoItem {todo} on:deleteTodo = {deleteTodo(todo)} /&gt;。请参阅 REPL
    • 你有let deleteTodo,但这是一个变量而不是函数定义,所以当你像函数一样调用它时不会发生任何事情。同样,正如 Leander 所说,如果您想使用事件处理程序将参数传递给函数,那么您调用它是错误的,它不会像 {function(arg)} 那样工作,您需要 {()=&gt; function(arg)}。这个答案是正确的。
    • 也许您想将在App.svelte 中声明的deleteTodo 函数传递给ToDoList。所以let deleteTodo; 必须变成export let deleteTodo; 并且&lt;ToDoList todos={todos} /&gt; 可以变成&lt;ToDoList todos={todos} deleteTodo={deleteTodo} /&gt; 或简写&lt;ToDoList {todos} {deleteTodo} /&gt;。这不是最好的模式,但它有效
    猜你喜欢
    • 2021-01-12
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 2016-06-17
    • 2021-02-21
    • 2017-05-19
    • 1970-01-01
    • 2011-06-08
    相关资源
    最近更新 更多