Komponen React tidak diperbarui setelah penyimpanan Redux berubah

Saya mencoba mengambil beberapa data dalam komponen reaksi menggunakan kait useEffect. Setelah render awal, fetchItems() mendapatkan item dan memperbarui toko. Namun, items masih berupa objek kosong bahkan setelah toko diperbarui.

Saya mungkin salah menggunakan useEffects. Bagaimana Anda menggunakan Redux dengan useEffects? Saya ingin menyetel status pemuatan untuk komponen, tetapi karena komponen hanya mengirimkan tindakan untuk mengambil item (alih-alih memanggil API secara langsung), ia tidak mengetahui kapan data diambil dan penyimpanan diperbarui sehingga dapat menariknya. .

Dapatkah seseorang membantu mencari cara untuk memastikan bahwa objek items diperbarui setelah pengambilan saga dan pembaruan toko berikutnya?

import React, { useState, useEffect } from "react";
import { connect } from 'react-redux';
import { useParams } from "react-router-dom";

const ItemComponent = ({ item, fetchItem }) => {
    const { itemId } = useParams();
    
    const [isLoading, setIsLoading] = useState(false);

    useEffect(() => {
        setIsLoading(true)
        fetchItem(itemId)
        setIsLoading(false)
    }, []);
    
    console.log(item) // gives empty object even after the fetch and store update
}

const mapStateToProps = (state) => {
  return {
    item: state.item
  }
}

const mapDispatchToProps = (dispatch) => {
    return {
        fetchItem: (itemId) => { dispatch(fetchItemActionCreator(itemId)) }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(ItemComponent);
  • fetchItemActionCreator adalah pembuat tindakan yang membuat tindakan untuk dikirim.
  • Peredam dan saga saya berfungsi dengan baik karena saya dapat melihat tindakan penyimpanan dan pembaruan di konsol.
  • Jika saya meneruskan objek items ke dalam array ketergantungan untuk useEffect, maka akan ada loop tak terbatas dan halaman terus dirender ulang.

Peredam:

const itemReducer = (state={}, { type, payload }) => { 
  switch(type) { 
  case ITEM_GET_SUCCESS: 
    return {...state, ...payload} 
  default: return state 
  } 
} 

ambilItemActionCreator:

import { createAction } from '@reduxjs/toolkit';

export const fetchItemActionCreator = createAction(ITEM_GET_PENDING);

Terima kasih banyak sebelumnya!


person Bovojon A    schedule 12.11.2020    source sumber
comment
Bisakah Anda membagikan item reducer dan dan fetchItemActionCreator Anda   -  person Hend El-Sahli    schedule 12.11.2020
comment
const ItemComponent = ({ item , fetchItem}) => { Apakah itu tidak disengaja?   -  person Hend El-Sahli    schedule 12.11.2020
comment
Baru saja menambahkan peredam dan pembuat tindakan. Dan ya, fetchItem secara tidak sengaja tidak ditambahkan di sini dalam pertanyaan   -  person Bovojon A    schedule 13.11.2020


Jawaban (1)


Saya ingin mengatur status pemuatan untuk komponen tersebut

/** Action */
const getItem = () => dispatch => {
  dispatch({ type: 'GET_ITEM_START' });

  axios
    .get('your api end point')
    .then(res => {
      const item = res.data;
      dispatch({
        type: 'GET_ITEM_SUCCESS',
        payload: {
          item,
        },
      });
    })
    .catch(error => {
      dispatch({
        type: 'GET_ITEM_FAIL',
        payload: error,
      });
    });
};

/** Reducer */
const INITIAL_STATE = {
  item: null,
  error: '',
  loading: false,
};

const itemReducer = (state = INITIAL_STATE, { type, payload }) => {
  switch (type) {
    case 'GET_ITEM_START':
      return { ...state, error: '', loading: true };

    case 'GET_ITEM_SUCCESS':
      return { ...state, ...payload, loading: false };

    case 'GET_ITEM_FAIL':
      return { ...state, error: payload, loading: false };

    default:
      return state;
  }
};

Kemudian Anda dapat menangani status Pemuatan di komponen Anda

  const ItemComponent = ({ fetchItem, item, loading, error }) => {
    /** ... */
    /**
      Check for loading and show a spinner or anything like that
    */

    useEffect(() => {
      fetchItem(itemId);
    }, []);

    if (loading) return <ActivityIndicator />;
    if (item) return <View>{/* renderItem */}</View>;
    return null;
  };
person Hend El-Sahli    schedule 12.11.2020
comment
Terima kasih telah membagikan ini @Hend El-Sahli. Apakah ada cara untuk melakukan ini dengan useEffect? Apakah Anda perlu mengambil data dari komponen itu sendiri? - person Bovojon A; 13.11.2020
comment
Terima kasih atas pembaruannya, @Hend El-Sahli. Saya bertanya-tanya, apakah saya tidak perlu meneruskan itemId ke array ketergantungan useEffect? - person Bovojon A; 16.11.2020