Не удается получить express API из интерфейса React - PullRequest
0 голосов
/ 23 марта 2020

Сейчас у меня третья неделя, когда я пытаюсь просто получить ответ json из Express API в приложение React. Я пробовал по крайней мере 40 часов уроков, и я все еще не могу заставить это работать. В отчаянии я пытаюсь опубликовать это здесь, зная, что меня линчуют, потому что это будет своего рода дубликат, но я ищу кого-то, кто пройдет мимо этого и, надеюсь, поможет мне понять, что я делаю неправильно.

В любом случае, вот API, который я пытаюсь вызвать:

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

app.use(express.static('jestproject'))
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

var todos = [{key:1, title:'eat'}, {key:2, title:'pray'}, {key:3, title:'love'}];

app.listen(3001, function (err) {
  if (err) {
  console.error('Cannot listen at port 3001', err);}
  console.log('Todo app listening at port 3001');
});

/////////////////////////////////////////////////////////////////////////////////
app.get('/', (req, res) => res.status(200).json(todos));

app.post('/post', (req, res) => {
    if(!req.body.title) {
        return res.status(400).send({
            success: 'false',
            message: 'title is required'
        });
    }

    const todo = {
        key: todos.length + 1,
        title: req.body.title
    }

    todos.push(todo);
    return res.send({todo})
});

app.put('/:key', (req, res) => {

    var key = parseInt(req.params.key, 10);

    if (todos[key - 1]){
        todos[key -1] = { 'key': key, title : req.body.title };
        res.status(200).send({
            success: 'true',
            message: 'Todo updated successfully'
        });
    } 
    else{
        res.status(404, 'The task is not found')
        .send()
    }
});

app.get('/:key', (req, res) => {

    const key = parseInt(req.params.key, 10);

    todos.map((todo) => {
        if (todo.key === key) {
            return res.status(200).send({todo});
        }
    });

    return res.status(404).send({
        success: 'false',
        message: 'todo does not exist'
    });
});

app.delete('/:key', (req, res) => {

    const key = parseInt(req.params.key, 10);

    todos.map((todo, index) => {
        if (todo.key === key) {
            todos.splice(index, 1);
            return res.status(200).send({
                success: 'true',
                message: 'Todo deleted successfuly',
            });
        }
    });

    return res.status(404).send({
        success: 'false',
        message: 'todo not found',
    });
});

app.put('/:key', (req,res) => {
    const key = parseInt(req.params.key);

    if(todos.key === key) {
        todo = req.body;

        return res.status(200).send({
            success: 'true',
            message: 'Todo Updated successfully',
        });
    }
});

module.exports = app;

Вот моя последняя попытка вызвать его из React

import React, { Component } from 'react';

class App extends Component {
   constructor(){
       super();
       this.state ={key: 0, title: ''};
   }
   componentDidMount() {
          fetch('http://localhost:3001/')
            .then(res => {
                console.log(res);
                return res.json()
             })
            .then(todos => { 
                console.log(todos); 
                this.setState({ todos })
             });
         }
   render() {
        return (
            <div className="App">
                <h1>todos</h1>
                {this.state.todos.map(todo =>
                <div key = {this.state.key} > title: {this.state.title} </div>
              )}
            </div>
        );
    }
}
export default App;

Это приводит к ошибке: Uncaught TypeError: Невозможно прочитать свойство 'map' из неопределенного

Может кто-нибудь объяснить, пожалуйста, правильный способ просто получить данные, поступающие в этом формате?

Ответы [ 3 ]

0 голосов
/ 23 марта 2020

ваш todos будет неопределенным во время начального render до запуска componentDidMount, поэтому вы должны инициализировать todos с пустым массивом, подобным этому

constructor(){
       super();
       this.state ={key: 0, title: '', todos: []};
   }
0 голосов
/ 23 марта 2020

Я думаю, что вы смешали состояние и массив задач. В конструкторе инициализируйте состояние так:

constructor(){
   super();
   this.state ={ todos: [key: 0, title: '']};
}

В функции рендеринга:

render() {
        return (
            <div className="App">
                <h1>todos</h1>
                {this.state.todos.map(todo =>
                <div key = {todo.key} > title: {todo.title} </div>
              )}
            </div>
        );
    }
0 голосов
/ 23 марта 2020

Вам нужно инициализировать задачи в конструкторе

constructor(){
       super();
       this.state ={key: 0, title: '', todos: []};
   }

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

Так что при попытке запустить .map на неопределенном, он вылетает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...