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

React中使用useContext传递函数失败,提示函数未定义求排查

问题:React useContext传递函数到孙组件时提示未定义

我尝试从App组件通过React useContext钩子向孙组件Tour传递removeItem函数,但在Tour组件中提示该函数未定义。以下是我的代码:

App.js

function App() {
    const API_URL = "https://course-api.com/react-tours-project";
    const [loading, setLoading] = useState(true);
    const [data, setData] = useState([]);

    async function getData() {
        const response = await fetch(API_URL);
        const data = await response.json();
        setData(data);
        setLoading(false);
    }

    useEffect(() => {
        getData();
    }, []);

    const removeItemContext = React.createContext();

    function removeItem(itemId) {
        const newData = data.filter((object) => object.id !== itemId);
        setData(newData);
    }

    if (loading) {
        return (
            <main>
                <Loading />
            </main>
        );
    }

    return (
        <main>
            <removeItemContext.Provider value={removeItem}>
                <Tours data={data} />
            </removeItemContext.Provider>
        </main>
    );
}

export default App;

Tour.js(孙组件)

import React, { useContext } from "react";
import removeItemContext from "./App";
function Tour(data) {
    const { id, name, info, image, price } = data;
    const deleteButton = useContext(removeItemContext);
    return (
        <article>
            <img src={image} alt={name} />
            <h2>{name}</h2>
            <span>{price}</span>
            <p>{info}</p>
            <button
                onClick={() => {
                    removeItem(id);
                }}
            >
                Not interested
            </button>
        </article>
    );
}

export default Tour;

问题分析与修复步骤

1. 错误点梳理

  • Context定义在App组件内部,外部组件无法正确导入该Context对象
  • Tour组件导入的是整个App组件,而非定义好的Context
  • useContext获取的函数赋值给了deleteButton,但点击事件里调用的是未定义的removeItem
  • Tour组件参数处理错误:直接解构data参数(实际是props对象),无法拿到正确的属性值

2. 修复后的代码

App.js 修改

将Context移到组件外部并导出:

import React, { useState, useEffect } from "react";
import Tours from "./Tours";
import Loading from "./Loading";

// 把Context定义在组件外部并导出
export const RemoveItemContext = React.createContext();

function App() {
    const API_URL = "https://course-api.com/react-tours-project";
    const [loading, setLoading] = useState(true);
    const [data, setData] = useState([]);

    async function getData() {
        const response = await fetch(API_URL);
        const data = await response.json();
        setData(data);
        setLoading(false);
    }

    useEffect(() => {
        getData();
    }, []);

    function removeItem(itemId) {
        const newData = data.filter((object) => object.id !== itemId);
        setData(newData);
    }

    if (loading) {
        return (
            <main>
                <Loading />
            </main>
        );
    }

    return (
        <main>
            <RemoveItemContext.Provider value={removeItem}>
                <Tours data={data} />
            </RemoveItemContext.Provider>
        </main>
    );
}

export default App;

Tour.js 修改

正确导入Context,处理props并调用正确的函数:

import React, { useContext } from "react";
// 导入正确的Context
import { RemoveItemContext } from "./App";

// 解构props里的data属性
function Tour({ data }) {
    const { id, name, info, image, price } = data;
    // 获取Context中的removeItem函数
    const removeItem = useContext(RemoveItemContext);
    return (
        <article>
            <img src={image} alt={name} />
            <h2>{name}</h2>
            <span>{price}</span>
            <p>{info}</p>
            <button onClick={() => removeItem(id)}>
                Not interested
            </button>
        </article>
    );
}

export default Tour;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 11:01:00