Приложение React с express и ax ios выдает ошибку при рендеринге данных - PullRequest
0 голосов
/ 12 января 2020

Я новичок в интерфейсных технологиях. Мое требование - сделать почтовый звонок на внешний сервер. Я начал с создания приложения реагирования и использовал ax ios для совершения звонка, но мне было отказано в доступе из-за CORS. В некоторых публикациях на stackoverflow упоминалось, что мне нужен прокси-сервер, чтобы преодолеть это. Таким образом, я добавил часть express в проект. Ниже мой код реакции и express.

React:

import React, { Component } from "react";

class App extends Component {
state = { posts: null };

componentDidMount() {
fetch("/posts")
  .then(res => {
    console.log(res);
    return res;
  })
  .then(posts => this.setState({ posts: posts }));
}

render() {
return (
  <div className="App">
    <h1>Users</h1>
    {this.state.posts}
  </div>
);
}
}

export default App;

Express:

var express = require("express");
var router = express.Router();
const axios = require("axios");

router.get("/", function(req, res, next) {
axios
.get("https://jsonplaceholder.typicode.com/posts")
.then(response => res.json(response.data))
.catch(err => next(err));
});

module.exports = router;

При загрузке приложения React появляется следующее сообщение об ошибке:

Error: Objects are not valid as a React child (found: [object Response]). If you meant to render a collection of children, use an array instead.

Ответы [ 4 ]

0 голосов
/ 12 января 2020

Две вещи:

1) Получите ваш результат из res.data, потому что fetch возвращает объект (data, statusText и т. Д. c), когда он разрешается, но вас больше всего беспокоит data

2) Добавить пустой массив в состояние state : { posts : []} и затем выполнить итерацию по массиву в методе рендеринга. Убедитесь, что вы не визуализируете объект. EG {{post.name}} вместо просто {{ post}}

0 голосов
/ 12 января 2020

Я протестировал приведенный ниже код, и он работал нормально. Запустите npm install --save axios раньше. В нем пропущено приложение express. js, но, возможно, оно будет полезным.

import React, {useState, useEffect} from 'react'
import ReactDOM from 'react-dom'
import Axios from 'axios'

const App = () => {

  const [posts, setPosts] = useState([])

  useEffect(() => {
    console.log('React works')
    Axios.get('http://jsonplaceholder.typicode.com/posts').then(res => {
      if (res.status === 200)
        setPosts(res.data)
      else
        console.log(res.status)
    }).catch(err => console.log(err))
  }, [])
	
  const mappedPosts = posts.map(post => <p key={post.id}>{post.title}</p>)

  return (
    <div className="App">
      {mappedPosts}
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'));
0 голосов
/ 12 января 2020

На самом деле в 2020 году нам не нужны классовые компоненты, componendDidMount и т. Д. c подробнее ... вы можете сделать четкий рефакторинг в вашем коде, например так:

import React, { useState, useEffect } from "react";

export default function App() {
    const [posts, setPosts] = useState([])

    useEffect(() => {
        async function getPosts(){
            const { data } = await fetch('/posts');
            setPosts(data);
        }

        getPosts();
    }, [])

    return (
        <div className="App">
           <h1>Users</h1>
           {posts.map(post => <p>{post}</p>}
        </div>
     );
}

0 голосов
/ 12 января 2020

Возвращенный ответ от топора ios fetch - это объект с полезной нагрузкой в ​​data. Так что вам нужно вернуть это:

componentDidMount() {
  fetch("/posts")
    .then(res => {
      console.log(res);
      return res.data;  // <-- res.data instead of res;
    })
    .then(posts => this.setState({ posts: posts }));
}
...