反应:“。map不是函数”问题

时间:2018-09-28 09:36:01

标签: javascript reactjs

有我收到此错误的示例代码:

我通过搜索组件收到此错误。我假设,我将state.books覆盖到该对象。但是,初中找不到解决方案。我应该如何正确更新state.books?

GetData.js

import React, { Component } from 'react';
import Search from '../pages/Search';
import CreateForm from '../components/CreateForm';
import axios from 'axios';

class GetData extends Component {
  state = {
    books: []
  };

  componentDidMount(){
    axios.get('/api/books/').then(res => {
      console.log(res);
      this.setState({
        books: res.data
      });
    });
  }

  addBook = (book) => {
    let books = [...this.state.books, book]
    axios.post('/api/books/', books).then(res => {
      console.log(res);
      this.setState({
        books: res.data
      });
    });
  }

  render() {
    return (
      <div className="app">
        <Search books={this.state.books} />
        <CreateForm addBook={this.addBook}/>
      </div>
    );
  }
}
export default GetData;

Search.js

import React from 'react';

const Search = ({books}) => {
  const bookElements = books.map(book => {
    return(
      <div className="book-data" key={book._id}>
        <div>{book.author}</div>
        <div>{book.publication}</div>
        <div>{book.publisher}</div>
      </div>
    )
  })

  return(
    <div className="book-elements">
      {bookElements}
    </div>
  )
}

export default Search;

CreateForm.js

import React, {Component} from 'react';

class CreateForm extends Component {
  state = {
    author: null,
    publication: null,
    publisher: null,
  };

  handleChange = (e) => {
    this.setState({
      [e.target.id]: e.target.value
    })
  }

  handleSubmit = (e) => {
    e.preventDefault();
    this.props.addBook(this.state);
  }

  render () {
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <label htmlFor="author">Author:</label>
          <input type="text" id="author" onChange={this.handleChange}/>
          <label htmlFor="publication">Publication:</label>
          <input type="text" id="publication" onChange={this.handleChange}/>
          <label htmlFor="publisher">Publisher:</label>
          <input type="text" id="publisher" onChange={this.handleChange}/>
          <button>Submit</button>
        </form>
      </div>
    )
  }
}

export default CreateForm;

api.js

const express = require('express');
const router = express.Router();
const Book = require('../models/book');

router.get('/books', function(req, res, next){
    Book.find({}).then(function(books){
        res.send(books);
    }).catch(next);
});

// Add a new book to the database.
router.post('/books', function(req, res, next){
    Book.create(req.body).then(function(book){
        res.send(book);
    }).catch(next);
});

// Update a book in the database.
router.put('/books/:id', function(req, res, next){
    Book.findByIdAndUpdate({_id: req.params.id}, req.body).then(function(){
        Book.findOne({_id: req.params.id}).then(function(book){
            res.send(book);
        });
    }).catch(next);
});

// Delete a book from the database.
router.delete('/books/:id', function(req, res, next){
    Book.findByIdAndRemove({_id: req.params.id}).then(function(book){
        res.send(book);
    }).catch(next);
});

module.exports = router;

和model.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// CREATE BOOK-DATA SCHEMA and MODEL
const bookSchema = new Schema({
    author: {
        type: String,
        required: [false, 'Author field is required'] 
    },

    publication: {
        type: String
    },

    publisher: {
        type: String
    },

    /*available: {
        type: Boolean,
        default: false
    }*/
});

const Book = mongoose.model('book', bookSchema);

module.exports = Book;

添加了api.js,它就是模型。是否有遗漏的东西? 添加了CreateForm.js,并且在此处传递新数据。状态定义错误吗?

3 个答案:

答案 0 :(得分:0)

这可能是因为books不是数组。始终遵循检查Array的方式,然后像映射一样。

const bookElements = Array.isArray(books) && books.map(book => {
    return( ...)

 const bookElements = Array.isArray(books) ? books.map(book => {
        return( ...) : // if not array then show some msg may b error/loader/empty list depending upon use case

为获得更好的解决方案,请提供更多详细信息,例如API回复等

答案 1 :(得分:0)

在执行.map或.forEach时始终进行条件检查

.return的地图

 const bookElements = books && books.map(book => {
    return(
      <div className="book-data" key={book._id}>
        <div>{book.author}</div>
        <div>{book.publication}</div>
        <div>{book.publisher}</div>
      </div>
    )
  })

.map不返回

const bookElements = books && books.map(book => (
      <div className="book-data" key={book._id}>
        <div>{book.author}</div>
        <div>{book.publication}</div>
        <div>{book.publisher}</div>
      </div>
    ))

答案 2 :(得分:0)

尝试一下:

1。客户端

App.js

addBook = book => {
    axios.post('/api/books/', book).then(res => {
      this.setState({
        books: [...this.state.books, res.data]
      });
    });
  }; 

2。服务器端

Api.js

router.post('/books', function(req, res, next) {
  const book = new Book(req.body);
  book
    .save()
    .then(book => res.send(book))
    .catch(next);
});

希望这会有所帮助!