繁体   English   中英

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

[英]could not find react-redux context value error triggering randomly

这是我的代码,用于在 JSON 中显示我的 Redux 商店 state 的内容:

   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 属性的按钮来调用另一个 function 时,我遇到了错误:

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 调用添加按钮的方法:

    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:

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>
      );
}

是什么导致异常? 任何建议将不胜感激。

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

  1. 您的App.js会创建一个 state,它在您的整个组件树之外,就像您一样

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

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

    重构该部分后,您可以在 ShowCustomerInfo 中使用此ShowCustomerInfo但您应该将其称为<ShowCustomerInfo/>而不是ShowCustomerInfo()因为它呈现JSX并且您应该再次这样做,因为您希望将此组件作为 React 数据流的一部分否则你只是把它当作普通的 function 对待。

  2. 这只是一个命名约定,但您的App.js文件没有定义<App/>组件,而只是呈现它。 我希望您的App.jsindex.js因为它将成为您的虚拟 dom 的开始ReactDOM.render

如果您考虑第一部分进行更改,您将摆脱我相信的问题。

您不能从诸如onClick类的事件处理程序呈现组件。 事件处理程序可以更新 state 并执行 API 调用等副作用,但它不能return任何内容。 如果您将组件称为 function 而不是正确渲染它们,那么您将收到类似“错误:找不到 react-redux 上下文值;请确保组件包装在<Provider> ”中的错误。

相反,您想从onClick处理程序更新 state,并根据 state 有条件地渲染不同的组件。 您可以使用某种值,例如boolean state showCustomerInfonumber state page 由于我们正在将数据加载到array customerInfo中,我们可以检查长度是否大于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>
  );
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM