Berikut adalah kode saya untuk menampilkan konten State Redux Store saya di JSON:

   function ShowCartContents() {
      // Convert object to JSON before rendering
      const cartContentsJSON = JSON.stringify(useStore().getState())
    
      return (
        <div>
            <h2>Cart contents: {cartContentsJSON}</h2>
          </div>
      );
    }
// Works fine

Semuanya berfungsi dengan baik tetapi ketika saya mencoba menambahkan tombol dengan atribut onclick untuk memanggil fungsi lain saya mendapatkan kesalahan:

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

Yang aneh di sini adalah bahwa saya memiliki <App> terbungkus <Provider> tetapi kesalahan ini terjadi dan saya tidak dapat menemukan logika mengapa ini terjadi. Ini adalah awal dari App.js saya:

    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([])

Inilah cara saya mencoba menambahkan tombol saya dengan onClick untuk panggilan fungsi:

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

Ini memicu kesalahan di atas. Ini adalah fungsi ShowCustomerInfo saya:

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

Apa yang menyebabkan pengecualian? Saran apa pun akan sangat dihargai.

1
Mr. Engineer 5 April 2021, 17:15

2 jawaban

Jawaban Terbaik

Anda tidak dapat membuat komponen dari handler acara seperti onClick. Seorang handler acara dapat memperbarui keadaan dan melakukan efek samping seperti panggilan API tetapi tidak dapat return apa-apa. Jika Anda menelepon komponen sebagai fungsi alih-alih membuatnya dengan benar maka Anda akan mendapatkan kesalahan seperti "kesalahan: tidak dapat menemukan nilai konteks reaksi-redux; pastikan komponen dibungkus dalam {{x2}".

Sebaliknya Anda ingin memperbarui status dari onClick handler Anda dan secara kondisional membuat komponen berbeda berdasarkan pada negara. Anda dapat menggunakan semacam nilai seperti boolean state showCustomerInfo atau number state page. Karena kami memuat data ke array}}, kami dapat memeriksa untuk melihat apakah panjangnya lebih besar dari 0 dan hanya menampilkan info pelanggan setelah itu tidak kosong.

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>
  );
};
0
Linda Paiste 5 April 2021, 18:38

Ada beberapa anti-pola yang saya lihat dalam kode Anda seperti:

  1. App.js Anda menciptakan keadaan yang berada di luar seluruh pohon komponen seperti yang Anda lakukan

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

    setelah membuat rootElement dan menggunakannya di ReactDOM.render. Anda harus membawa keadaan ini menjadi yang sebenarnya komponen karena negara mana pun harus menjadi bagian dari reaksi DataFlow tetapi apa yang Anda lakukan sebenarnya melanggar ini.

    Setelah refactoring bagian itu Anda dapat menggunakan keadaan ini dalam {{x0} Anda} tetapi Anda harus menyebutnya sebagai <ShowCustomerInfo/> bukan ShowCustomerInfo() karena render JSX dan sekali lagi Anda harus melakukan ini, karena Anda ingin membuat komponen ini bagian dari aliran data yang bereaksi jika Anda hanya memperlakukannya seperti fungsi reguler.

  2. Ini hanya konvensi penamaan tetapi file App.js Anda tidak define <App/> komponen tetapi hanya membuatnya. Saya harapkan App.js Anda menjadi index.js karena itu akan menjadi Awal virtual-dom Anda dengan ReactDOM.render.

Jika Anda membuat perubahan mengingat bagian pertama, Anda akan menyingkirkan masalah yang saya percayai.

1
Furkan Kalaycioglu 5 April 2021, 14:58