首页 > 解决方案 > 来自消费者的反应上下文值始终是它们的初始值

问题描述

我正在使用 React 上下文来传递数据,遵循docs,但是我坚持使用初始值并且不确定我做错了什么。

这是我的上下文文件的样子:

export const ItemsContext = createContext([]);
ItemsContext.displayName = 'Items';


export const ItemsProvider = ({ children }) => {
    const [items, setItems] = useState([]);
    const [loading, setLoading] = useState(false);

    const setData = async () => {
        setLoading(true);
        setItems(await getItemsApiCall());
        setLoading(false);
    };

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

    console.warn('Items:', items); // This shows the expected values when using the provider
    return (
        <ItemsContext.Provider value={{ items, loading }}>
            {children}
        </ItemsContext.Provider>
    );
};

现在,我想在相关组件中将这些项目输入我的应用程序。我正在执行以下操作:

const App = () => {
    return (
        <ItemsContext.Consumer>
            {(items) => {
                console.warn('items?', items); // Is always the initial value of "[]"
                return (<div>Test</div>);
            }}
        </ItemsContext.Consumer>
    );
}

但是,正如我的评论所述,items将始终为空。另一方面,如果我只使用ItemsProvider,我确实得到了正确的值,但此时需要直接在应用程序上访问它,所以ItemsContext.Consumer似乎更有意义。

我在这里做错了吗?

编辑:一种解决方法似乎是用 包裹ConsumerProvider但这感觉不对,在文档中没有看到。可能是这样吗?

所以本质上是这样的:

const App = () => {
    return (
    <ItemsProvider>
        <ItemsContext.Consumer>
            {(items) => {
                console.warn('items?', items); // Is always the initial value of "[]"
                return (<div>Test</div>);
            }}
        </ItemsContext.Consumer>
    </ItemsProvider>
    );
}

标签: javascriptreactjsreact-hooksreact-context

解决方案


您必须ItemsContext在组件层次结构之上提供提供程序App,否则将使用上下文的默认值。这种形式的东西:

    <ItemsContext.Provider value={...}>
        <App/>
    </ItemsContext.Provider>

推荐阅读