Состояние Redux из действий и редукторов не отображается в mapStateToProps - PullRequest
1 голос
/ 13 июля 2020

У меня есть файл действий с именем menu, в котором используется ax ios для получения данных JSON из серверного API. Затем у меня есть редукторы, которые вызываются в файле MainMenu. js, который получает данные. Все данные отображаются в инструментах разработки Redux. Однако я могу получить доступ только к данным, которые у меня есть в intitialState. Должен быть массив из трех элементов, но он показывает только первый в intitialState. Данные из редукторов не отображаются, когда я пытаюсь выполнить console.log. Поэтому, очевидно, я не смог бы отобразить его в DOM.

Redux Dev Tools Javascript Console

actions/menu.js

import { ADD_PRODUCT, GET_PRODUCTS, GET_PRODUCT } from './types';
import axios from 'axios';

export const getProducts = () => (dispatch) => {
    axios
        .get('http://localhost:8080/menu')
        .then((response) => {
            // console.log(response);
            const data = response.data;
            dispatch({
                type: GET_PRODUCTS,
                payload: { data },
            });
        })
        .catch((err) => {
            console.log(err);
        });
};

export const getProduct = (product) => (dispatch) => {
    axios
        .get(`http://localhost:8080/menu/${product}`)
        .then((response) => {
            // console.log(response);
            const data = response.data;
            dispatch({
                type: GET_PRODUCT,
                payload: { data },
            });
        })
        .catch((err) => {
            console.log(err);
        });
};

redurs / index. js

import { combineReducers } from 'redux';
import menu from './menu';

export default combineReducers({ menu });

редукторы / меню. js

import { GET_PRODUCTS, GET_PRODUCT } from '../actions/types';

const intitialState = [
    {
        test: 'Test',
    },
];

export default function (state = intitialState, action) {
    const { type, payload } = action;

    switch (type) {
        case GET_PRODUCTS:
            return [...state, payload];
        case GET_PRODUCT:
            return [...state, payload];
        default:
            return [...state];
    }
}

компоненты / MainMenu. js

import React, { Fragment, useEffect } from 'react';
import { connect } from 'react-redux';
import { getProducts, getProduct } from '../actions/menu';

const MainMenu = ({ getProducts, getProduct, menu }) => {
    useEffect(() => {
        getProducts();
        getProduct('b4bc2e28-21a3-47ea-ba3b-6bad40b35504');
        console.log(menu);
    }, []);
    return <Fragment></Fragment>;
};

const mapStateToProps = (state) => ({
    menu: state,
});

export default connect(mapStateToProps, { getProducts, getProduct })(MainMenu);

1 Ответ

0 голосов
/ 13 июля 2020

Я создал рабочее решение, используя тернарный оператор. Сначала выполняется проверка, все ли элементы в массиве загружены. Если они не все загружены, отображается div с незагруженными данными. В противном случае данные отображаются в DOM.

import React, { Fragment, useEffect } from 'react';
import { connect } from 'react-redux';
import { getProducts, getProduct } from '../actions/menu';

const MainMenu = ({ getProducts, getProduct, menu }) => {
    useEffect(() => {
        getProducts();
        getProduct('b4bc2e28-21a3-47ea-ba3b-6bad40b35504');
    }, []);
    if (menu.length <= 2) {
        console.log('Data Not Loaded');
    } else {
        console.log('Data', menu[2].data.name);
    }
    return (
        <Fragment>
            <div>{menu.length <= 2 ? <div>Data not loaded</div> : <div>{menu[2].data.name}</div>}</div>
            <div>
                {menu.length <= 2 ? (
                    <div>Data not loaded</div>
                ) : (
                    <div>
                        {menu[1].data.map((food) => (
                            <div>{food.name}</div>
                        ))}
                    </div>
                )}
            </div>
        </Fragment>
    );
};

const mapStateToProps = (state) => ({
    menu: state.menu,
});

export default connect(mapStateToProps, { getProducts, getProduct })(MainMenu);
...