找不到随机触发的react redux上下文值错误



以下是我在JSON中显示Redux存储状态内容的代码:

function ShowCartContents() {
// Convert object to JSON before rendering
const cartContentsJSON = JSON.stringify(useStore().getState())

return (
<div>
<h2>Cart contents: {cartContentsJSON}</h2>
</div>
);
}
// Works fine

一切都很好,但当我试图添加带有onClick属性的按钮来调用另一个函数时,我遇到了错误:

Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider>

奇怪的是,我确实将<App>封装在<Provider>中,但出现了这个错误,我找不到发生这种情况的任何逻辑。这是我的App.js:的开始

import './App.css';
import MenuItems from './components/Navbar/MenuItems';
import ReactDOM from 'react-dom';
import React, { useState } from 'react';
import { createStore } from 'redux';
import {AddItemToCart, DeleteItemFromCart, Counter} from './cart.js';
import Header from './header';
import Footer from './footer.js';
import { render } from "react-dom";
import { Provider } from "react-redux";
import { useSelector, useStore } from 'react-redux';

let store = createStore(Counter);
const rootElement = document.getElementById("root");
render(
<Provider store={store}>
<App />
</Provider>,
rootElement
);
const [customerInfo, setCustomerInfo] = useState([])

以下是我如何尝试使用OnClick为函数调用添加按钮:

function ShowCartContents() {
const cartContentsJSON = JSON.stringify(useStore().getState())

return (
<div>
<h2>Cart contents: {cartContentsJSON}</h2>
<button onClick={(e)=> {ShowCustomerInfo(e)}}>Proceed</button>
// Also tried: <button onClick={<ShowCustomerInfo/>}>Proceed</button>
</div>
);
}

这会触发上面的错误。这是我的ShowCustomerInfo函数:

function ShowCustomerInfo(){
fetch(`http://127.0.0.1:5000/getCustomerInfo`)
.then(response => response.json())
.then(response => {
setCustomerInfo(response.result);
console.log(response.result);
});
return (
<div>
<h2>
{customerInfo}
</h2>
</div>
);
}

是什么导致了异常?如有任何建议,我们将不胜感激。

不能从事件处理程序(如onClick(中呈现组件。事件处理程序可以更新状态并执行副作用,如API调用,但不能执行return。如果你把组件作为一个函数调用,而不是正确地渲染它们,那么你会得到像"这样的错误;错误:找不到react redux上下文值;请确保该部件被包裹在CCD_ 7"中;。

相反,您希望从onClick处理程序更新状态,并根据状态有条件地呈现不同的组件。您可以使用某种值,如boolean状态showCustomerInfonumber状态page。由于我们正在将数据加载到arraycustomerInfo中,因此我们可以检查长度是否大于0,并且只有在不为空时才显示客户信息。

export const App = () => {
const [customerInfo, setCustomerInfo] = useState([]);
// use this state so that we can disable hide the "Proceed"
// button immediately, before the fetch has completed
const [isLoading, setIsLoading] = useState(false);
const state = useSelector((state) => state);
const cartContentsJSON = JSON.stringify(state);
function loadCustomerInfo() {
console.log("clicked");
// can use async/await, but fetch is fine too
setIsLoading(true);
fetch(`http://127.0.0.1:5000/getCustomerInfo`)
.then((response) => response.json())
.then((response) => {
setIsLoading(false);
// could store this in redux instead
setCustomerInfo(response.result);
})
.catch((error) => {
console.error(error);
setIsLoading(false);
});
}
return (
<div>
<h2>Cart contents: {cartContentsJSON}</h2>
<button disabled={isLoading} onClick={() => loadCustomerInfo()}>
Proceed
</button>
{customerInfo.length > 0 && (
<div>
<h3>Customer Info</h3>
<p>{JSON.stringify(customerInfo)}</p>
</div>
)}
</div>
);
};

我在你的代码中看到了一些反模式,比如:

  1. 您的App.js创建了一个位于整个组件树

    const [customerInfo, setCustomerInfo] = useState([])

    创建rootElement并在中使用之后ReactDOM.render。您必须将此状态带入实际任何状态的组件都必须是React的一部分数据流,但你所做的实际上违反了这一点。

    重构该部分后,您可以使用此状态在您的ShowCustomerInfo中但是你应该把它称为<ShowCustomerInfo/>,而不是ShowCustomerInfo(),因为它呈现JSX,你应该再次这样做,因为你想让这个组件成为React数据流的一部分,否则你只是把它当作一个常规函数。

  2. 这只是一个命名约定,但App.js文件不是定义<App/>组件,但只是渲染它你的App.js将是index.js,因为它将是以ReactDOM.render开始您的虚拟dom。

如果你在考虑第一部分的情况下进行更改,我相信你会解决这个问题。

相关内容

  • 没有找到相关文章

最新更新