Компонент React ломается? Я не могу понять почему

Мой компонент получает массив объектов с сервера и устанавливает его в объект this.state. Но в момент рендеринга (this.state обновлен до this.setState() из-за метода выборки в настоящий момент componentWillMount(){}) я не могу нормально работать с массивом внутреннего состояния. Почему? Он выводит мне, что массив не определен внутри функции render(){}, и я также не могу получить recipes.length массива.

Вот код Компонента:

import React, { Component } from "react";
import { Router, Route, Link, Switch} from 'react-router';
import '../css/Recipes.css';
import EditRecipe from '../js/EditRecipe';
import DeleteRecipe from '../js/DeleteRecipe';
import CreateProposal from '../js/CreateProposal';
import CreateRecipe from "./CreateRecipe";

class Recipes extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            recipes: [] 
        };
        this.renderRec = this.renderRec.bind(this);
        this.getRec = this.getRec.bind(this);
    }
    renderRec(recipe){
        return <div key = {recipe.id}>{recipe.name}</div>
    }
    componentWillMount(){
        this.getRec();
    }
    getRec(_){
        fetch('http://localhost:5000/recipes')
        .then(response => response.json())
        .then(data => {
            this.setState({recipes: data});
        })
        .catch(err => console.info(err))
    }
    render() {
        const recipes = this.state.recipes;
        const howManyRecipes = recipes.length;
        console.info(recipes.data.length);
        const view = howManyRecipes > 0 ? <Route component = {this.state.recipes.map(this.renderRec)} /> : <Route component = {CreateProposal}/>;
        console.info(view);
        return (
            <div>
                <div>Our community did {howManyRecipes} recipes</div>
                {view}
            </div>     
        );
    }
}

export default Recipes;
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

console.info (recipes.data.length); должен быть console.info (recipes.length); для регистрации правильной информации

Lyubomir 23.04.2018 11:23
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
95
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Проблема исходит из

console.info(recipes.data.length);

до того, как componentWillMount отобразит, у вас есть:

 recipes = this.state.recipes = []

Следовательно, recipes.data не определен и не может получить значение длины.

Либо удалите строку, либо измените ее на (например):

console.info(recipes.data ? recipes.data.length : recipes.data);

Во-первых, вам следует избегать вызова api в componentWillMount, вместо этого переместите его на componentDidMount.

Второй,

recipes.data не всегда определяется. Он всегда будет определен после успешного вызова API.

Ответ принят как подходящий

Избегайте использования ловушки жизненного цикла componentWillMount для асинхронных операций. Вместо этого используйте componenDidMount.

Фактическая проблема заключается в том, что ваш запрос может занять слишком много времени, поэтому он не будет установлен при первоначальном рендеринге, поэтому ваш массив останется пустым, как в исходном состоянии.

componentWillMount() is invoked immediately before mounting occurs. It is called before render(), therefore setting state in this method will not trigger a re-rendering. Avoid introducing any side-effects or subscriptions in this method.

См. Больше в документы.

Другие вопросы по теме