开发者问题收集

如何在 React.js 前端应用程序中显示来自 Rails 5 API 的数据?

2018-11-06
1117

我已经使用 Rails 设置了一个 API,其中 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"}]

我现在正尝试在使用 Create React App 构建的 React.js 前端应用程序中简单地显示这些数据(理想情况下是无序列表),这是我的 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:无法将未定义或 null 转换为对象
  • 意外的标记,预期为“,”
  • 编译失败:'word' 未定义 no-undef

解决方案在 这篇文章 让我找到了现在的代码,但是我在构建 React 应用程序的方式上缺少了一些东西:你能给我指明正确的方向吗?

3个回答
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>
 )
}
Krina Soni
2018-11-06

问题出在这里: let {words, word} = this.state ; this.state 还没有 word 属性。您可以像这样初始化 this.state

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

请随意询问

Evgeniy Boytsov
2018-11-06

问题中的代码有两个问题:

  1. wordsword 未定义。
  2. render() 函数中对 words 的迭代未使用 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;
Thibaud Clement
2018-11-06