ReactJS с сокетами Проблема с вложенными данными анализа JSON

У меня есть файл JSON со структурой типа "data.json"

{
    "Object1": {
        "name": "1",
        "rank": "2"
    },
    "Object2": {
        "name": "3",
        "rank": "4"
    }
}

и в моем коде React у меня есть данные для установки моего состояния реакции. Я хочу передать Object2 другому компоненту, но не могу различать данные.

// import packages
import React, { Component } from "react";
import io from 'socket.io-client';

class App extends Component {
    constructor() {
        super();

        this.state = {
            data: null
        };
        this.socket = io('http://localhost:5000');

        // Binders
        this.updateState = this.updateState.bind(this);
    }

    componentDidMount() {
        this.socket.on('send data', this.updateState);
    }

    updateState(result) {
        this.setState({
            data: result
        });
    }

    render() {
        return (
            <p style = {{ textAlign: "center" }}>
                {this.state.data}
            </p>
        );
    }
}

export default App;

Когда я пытаюсь сослаться на что-то вроде this.state.data или this.state.data.Object1.name, он указывает на нулевой объект. Что я делаю не так?

Поместите console.info(this.state) перед return в методе render. Что вы видите во втором рендере? Кроме того, вы не можете напрямую отображать объекты в DOM. Это не работает: {this.state.data}.

devserkan 16.08.2018 04:37

@devserkan, я вижу данные на моей пустой домашней странице и консоли. Почему this.state.data не работает? Это работает, но не так, как я пытаюсь заставить его работать. Я пропускаю все через сокет, чтобы полностью обновить приложение за один раз.

Imran 16.08.2018 04:43

это потому, что это не Object1, а Object11?

azium 16.08.2018 04:46

@azium это просто опечатка. Это не имеет значения. gyazo.com/150dd6bd270513982357022d7dc73570

Imran 16.08.2018 04:49

о, ошибка на вашем скриншоте отличается от того, что вы сказали. он не говорит, что Object1 равен нулю, он говорит, что data равен нулю. @devserkan ответ правильный

azium 16.08.2018 04:54

Я просто делаю слепое предположение, так как ваш код выше кажется прекрасным. Но как только вы укажете что-то вроде this.state.data.Object1.name в своей функции рендеринга, вы сначала получите нулевую ошибку, потому что сокет еще не вернул никаких данных. В этом случае вы можете выполнить нулевую проверку в начале вашей функции рендеринга и убедиться, что у вас действительно есть данные.

ced-b 16.08.2018 04:58
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
1
6
45
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Я не так много знаю о сокетах, но поскольку вы устанавливаете состояние после первого рендеринга, данных нет, пока componentDidMount не завершит свою работу. Итак, вам нужен условный рендеринг.

const data = {
  "Object1": {
    "name": "1",
      "rank": "2"
  },
  "Object2": {
    "name": "3",
      "rank": "4"
  }
};

const fakeRequest = () => new Promise( resolve => 
  setTimeout( () => resolve(data), 2000 )
);

class App extends React.Component {
  state = {
    data: null,
  };

  componentDidMount() {
    fakeRequest().then( data => this.setState({data}));
  }

  render() {
    return <div>
      {!this.state.data ? "No data yet, wait 2 seconds." : this.state.data.Object1.name }
    </div>;
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<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>
<div id = "root"></div>

Вы не можете использовать {this.state.data}, поскольку дочерний элемент React не может быть объектом. Вам нужно использовать значения этого объекта.

Я понимаю, в чем проблема, но я использую сокет, это сработало бы, если бы я использовал API. Постараюсь возиться и посмотреть, что я могу сделать

Imran 16.08.2018 05:21

Итак, socket.on () - это обратный вызов, и я устанавливаю состояние через обратный вызов оттуда. Как я могу позволить setState завершиться перед рендерингом? Я не могу понять.

Imran 16.08.2018 07:17

В чем разница использования сокета или получения данных из API здесь? В какой-то момент вы правильно понимаете данные? И, полагаю, он идет, как ручей. Итак, условный рендеринг должен работать. Вы не можете позволить setState завершить работу до первого рендеринга или приостановить рендеринг каким-либо образом. Ваш компонент монтируется и попадает в первый рендер перед componentDidMount. Вот почему мы используем здесь условный рендеринг.

devserkan 16.08.2018 14:17

Совершенно верно. Придется попробовать, когда вернусь домой. Я считаю, что ваш ответ правильный. Логически это имеет смысл, просто моя реализация неверна, и теперь я это понимаю.

Imran 16.08.2018 22:09

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