In einer React Redux App habe ich eine Komponente namens ItemDetail, die natürlich alle Details zu dem Element, das sie abruft, basierend auf dem URL-Parameter id rendern soll.

import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux'
import * as actions from '../../../../../actions'

const ItemDetail = (props) => {
    const mapState = (state) => {
        return {
            currentItem: state.currentItem,
        }
    }

    const dispatch = useDispatch()
    const { currentItem } = useSelector(mapState)



    useEffect(() => {
        let { id } = props.match.params
        dispatch(actions.fetchCurrentItem(id))
        dispatch(actions.setAside(false))
        return () => dispatch(actions.setAside(true))
    }, [dispatch, props.match.params])



    return (

        <div id="item-detail">
            <div id="picture">picture {currentItem.image}</div>
            <div id="details">details {currentItem.name} {currentItem.rating[1]}</div>
        </div>
    );
}

export default ItemDetail;

Ein Item Objekt würde folgendermaßen aussehen:

{
      "id": 1,
      "name": "Dell XPS 13",
      "value": "dell-xps-13",
      "category": 2,
      "department": 2,
      "price": 1599.0,
      "discount": 0,
      "image": "xps13_9370_4_3_01.jpg",
      "rating": {
        "1": 1,
        "2": 0,
        "3": 8,
        "4": 12,
        "5": 21
      },
      "sold": 520,
      "left": 34,
      "features": [
        "10th Generation Intel® Core™ i7-1065G7 Processor",
        "6.8% larger 16:10 display - 13 inches, 17% larger touchpad and an edge-to-edge backlit keyboard with larger key caps",
        "6% thinner design with more power",
        "long battery life —up to 18 hours, 49 minutes* on a Full HD+ model when using when using productivity applications like Word or Excel or up to 11 hours, 51 minutes* when streaming Netflix"
      ]
}

Jetzt kann ich auf jeden einzelnen Schlüssel außer "Bewertung" zugreifen. Wenn ich versuche, auf {currentItem.rating [1]} zuzugreifen, wird der folgende Fehler TypeError: Cannot read property '1' of undefined angezeigt. Es sieht so aus, als ob das Objekt undefiniert ist, aber wenn ich nur versuche, auf {currentItem.rating} zuzugreifen, ohne den Schlüsselwert anzugeben, erhalte ich wie erwartet Error: Objects are not valid as a React child (found: object with keys {1, 2, 3, 4, 5}). If you meant to render a collection of children, use an array instead..

Wie kommt es also, wenn ich versuche, auf einen anderen Wert zuzugreifen oder einfach rating das Objekt gefunden wird, aber wenn ich versuche, auf den Objektschlüssel (in diesem Fall '1') zuzugreifen, ist das Objekt undefiniert?

Vielen Dank für jede Antwort.

BEARBEITEN

Ich habe das Gefühl, dass das Problem in meinem Reduzierer liegt. Nur für den Fall, hier ist es.

import * as actions from './../actions'

const initState = {
    loading: false,
    categories: [],
    currentCategory: {
        "id": 1,
        "value": "any",
        "name": "--- Any ---",
        "departments": []
    },
    currentDepartment: {
        "id": 0,
        "value": "any",
        "name": "--- Any ---",
    },
    toggler: 'hidden',
    error: '',
    minimumPrice: 0,
    maximumPrice: 5000,
    items: [],
    valueSearched: '',
    currentItem: {},
    aside: true
}

const rootReducer = (state = initState, action) => {
    switch (action.type) {
        case actions.SET_CATEGORY:
            return {
                ...state, currentCategory: action.payload.category, departments: action.payload.departments, currentDepartment: {
                    "id": 0,
                    "value": "any",
                    "name": "--- Any ---",
                }
            }
        case actions.FETCH_CATEGORIES_REQUEST:
            return { ...state, loading: true }
        case actions.FETCH_CATEGORIES_SUCCESS:
            return { ...state, loading: false, categories: action.payload }
        case actions.FETCH_CATEGORIES_FAILURE:
            return { ...state, loading: false, categories: action.payload }
        case actions.SET_DEPARTMENT:
            return { ...state, currentDepartment: action.payload }
        case actions.TOGGLE:
            return { ...state, toggler: action.payload }
        case actions.ASIDE:
            return { ...state, aside: action.payload }
        case actions.SET_MINIMUM_PRICE:
            return { ...state, minimumPrice: action.payload }
        case actions.SET_MAXIMUM_PRICE:
            return { ...state, maximumPrice: action.payload }
        case actions.FETCH_ITEMS_REQUEST:
            return { ...state, loading: true }
        case actions.FETCH_ITEMS_SUCCESS:
            return { ...state, loading: false, items: action.payload }
        case actions.FETCH_ITEMS_FAILURE:
            return { ...state, loading: false, items: action.payload }
        case actions.SET_VALUE_SEARCHED:
            return { ...state, valueSearched: action.payload }
        case actions.FETCH_CURRENT_ITEM_REQUEST:
            return { ...state, loading: true }
        case actions.FETCH_CURRENT_ITEM_SUCCESS:
            return { ...state, loading: false, currentItem: action.payload, aside: false }
        case actions.FETCH_CURRENT_ITEM_FAILURE:
            return { ...state, loading: false, currentItem: action.payload }
        default:
            return state
    }
}

export default rootReducer
0
Mirko Oricci 12 Aug. 2020 im 15:19

2 Antworten

Beste Antwort

Ok, nach einer Recherche habe ich die Lösung gefunden.

Grundsätzlich ist meine Frage ein Duplikat von dies.

In meinem Fall muss ich nur currentItem: null in meinem Reduzierer in den Ausgangszustand versetzen und dann in meiner Komponente return prüfen, ob currentItem nicht null ist, wenn ja, wenn ja, Ich rendere einfach die gesamte Komponente.

0
Mirko Oricci 12 Aug. 2020 im 15:42

Sie können folgendermaßen darauf zugreifen:

{currentItem.rating["1"]}

Weil Ihr Objekt die Reihenfolge "Zeichenfolge" hat

UPDATE: Überprüfen Sie diesen Code. Es gehört nicht ganz Ihnen, aber ich denke, es hilft Ihnen, das Problem zu lösen.

<div id="details">raiting {Object.values(item.rating).join(",")} </div>

https://codesandbox.io/s/fancy-field-j5j61?file=/src/MyComp.js

0
Vova 12 Aug. 2020 im 14:05