Как отобразить данные из Rails 5 API в приложении внешнего интерфейса React.js? - PullRequest
0 голосов
/ 06 ноября 2018

Я настроил API с Rails, с конечной точкой http://localhost:3001/api/words, которая предоставляет следующие данные:

[{"id":1,"term":"Reach","definition":"Reach is the number of people who had any content from your Page or about your Page enter their screen.","example":"","author":"Loomly","credit":"https://www.loomly.com/","created_at":"2018-11-02T03:21:20.718Z","updated_at":"2018-11-02T03:21:20.718Z"},{"id":2,"term":"Emoji","definition":"A small digital image or icon used to express an idea, emotion, etc., in electronic communication","example":"","author":"Loomly","credit":"https://www.loomly.com/","created_at":"2018-11-02T03:23:50.595Z","updated_at":"2018-11-02T03:23:50.595Z"}]

Я сейчас пытаюсь просто отобразить эти данные (в идеале в виде неупорядоченного списка) в приложении внешнего интерфейса React.js, созданном с Create React App, и вот содержимое моего App.js файла:

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  constructor () {
    super()
    this.state = {}
    this.getWords = this.getWords.bind(this)
    this.getWord = this.getWord.bind(this)
  }

  componentDidMount () {
    this.getWords()
  }

  fetch (endpoint) {
    return window.fetch(endpoint)
      .then(response => response.json())
      .catch(error => console.log(error))
  }

  getWords () {
    this.fetch('/api/words')
      .then(words => {
        if (words.length) {
          this.setState({words: words})
          this.getWord(words[0].id)
        } else {
          this.setState({words: []})
        }
      })
  }

  getWord (id) {
    this.fetch(`/api/words/${id}`)
      .then(word => this.setState({word: word}))
  }

  render () {
    let {words, word} = this.state
    return (
      <div>
        {Object.keys(words).map((key) => {
          return (
            <div key={word.id}>
              <p>{word.term}</p>;
            </div>
          )
        })}
      </div>
    )
  }
}

export default App;

Я считаю, что проблема находится в следующей области кода:

render () {
  let {words, word} = this.state
    return (
      <div>
        {Object.keys(words).map((key) => {
          return (
            <div key={word.id}>
              <p>{word.term}</p>;
            </div>
          )
        })}
      </div>
    )
}

Я пытался выполнить шаги, описанные в этого урока , а также в этого другого урока , сохраняя при этом макет страницы максимально простым (без колокольчиков и свистит с semantic-ui-css), и что бы я ни пытался, я постоянно получаю следующие ошибки:

  • TypeError: Cannot convert undefined or null to object
  • Unexpected token, expected “,”
  • Failed to compile: 'word' is not defined no-undef

Решение, объясненное в этой статье , привело меня к коду, который у меня есть сейчас, но есть кое-что, чего мне не хватает в способе структурирования моего приложения React: можете ли вы указать мне правильное направление?

Ответы [ 3 ]

0 голосов
/ 06 ноября 2018

Проблема здесь: let {words, word} = this.state; this.state пока не имеет свойства слова. Вы можете инициализировать this.state следующим образом:

this.state = {
   words: [],
   word: {}
};

не стесняйтесь спрашивать

0 голосов
/ 06 ноября 2018

Есть две проблемы с кодом в вопросе:

  1. words & word не определены.
  2. Итерация по words в функции render() не была правильно установлена ​​с keys.

Благодаря ответам и комментариям, оставленным на этот вопрос, вот код, который я использовал в итоге:

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  constructor () {
    super()
    this.state = {
      words : [],
      word : {}
    }
    this.getWords = this.getWords.bind(this)
    this.getWord = this.getWord.bind(this)
  }

  componentDidMount () {
    this.getWords()
  }

  fetch (endpoint) {
    return window.fetch(endpoint)
      .then(response => response.json())
      .catch(error => console.log(error))
  }

  getWords () {
    this.fetch('/api/words')
      .then(words => {
        if (words.length) {
          this.setState({words: words})
          this.getWord(words[0].id)
        } else {
          this.setState({words: []})
        }
      })
  }

  getWord (id) {
    this.fetch(`/api/words/${id}`)
      .then(word => this.setState({word: word}))
  }

  render () {
    let {words} = this.state
    return (
      <ul className="words-container">
        {Object.keys(words).map((key) => {
          return (
            <li className="word-container" key={key}>
              {words[key].term}: {words[key].definition}.
            </li>
          )
        })}
      </ul>
    )
  }
}

export default App;
0 голосов
/ 06 ноября 2018

getWords () {    
  fetch('http://localhost:3001/api/words')
  .then((response) => {
    return response.json();
  })
  .then((res) => {
    // console.log(res); you should get the response you mentioned
    this.setState({words: res});
  });
}

Затем проверьте, получаете ли вы данные в своем штате, утешая их.

Тогда вы можете работать над этим, используя

render{
 return(
   <div>
     { this.state.words.map((val) => (
         <span>{val.term}</span>
     ))}
   </div>
 )
}
...