【问题标题】:How to display data from Rails 5 API in React.js frontend app?如何在 React.js 前端应用程序中显示来自 Rails 5 API 的数据?
【发布时间】:2018-11-06 06:24:56
【问题描述】:

我已经使用 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>
    )
}

我尝试按照this tutorial 和that other tutorial 中说明的步骤进行操作,同时保持页面布局尽可能简单(semantic-ui-css 没有花里胡哨),无论如何我尝试,我不断进入以下错误:

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

this article 中解释的解决方案让我找到了我现在拥有的代码,但我在构建 React 应用程序的方式上缺少一些东西:你能指出我正确的方向吗?

【问题讨论】:

  • 开头this.state是空对象,所以render中的words和word是undefined。同样来自给定信息words 似乎是一个数组,所以键代表索引。 /api/words/${id} 返回的数据是否与您在 words[0] 中的数据不同?

标签: javascript ruby-on-rails json reactjs rails-api


【解决方案1】:

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>
 )
}

【讨论】:

    【解决方案2】:

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

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

    欢迎提问

    【讨论】:

    • Evgeniy Boytsov 非常感谢,这有助于解决与单词和单词未定义相关的问题。
    【解决方案3】:

    题中的代码有两个问题:

    1. words & word 未定义。
    2. render() 函数中的 words 迭代未使用 keys 正确设置。

    感谢这个问题留下的答案和 cmets,这是我最终使用的代码:

    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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-28
      • 2017-12-22
      • 2017-10-16
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多