javascript - React: ".map is not a function" Issue
问题描述
There is the sample code that I received this error:
I'm getting this error via Search component. I assume , I'm overriding state.books to the object. However, can't find the solution as a junior. How should I update state.books correctly ?
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;
and 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;
Added api.js and that's model. Is there missing something ? Added CreateForm.js and there is the place where I'm passing the new data. Is state definition wrong ?
解决方案
This might be because books
is not Array. Always follow practice of checking Array and then map like.
const bookElements = Array.isArray(books) && books.map(book => {
return( ...)
or
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
For better solution provide more details like API reply etc
推荐阅读
- java - Spring:如何在 Spring Boot 中动态创建类似的 bean?
- c# - 当我无权访问 HttpContext 时,如何填充我的审核日志 UserId 字段?
- python - 如何在自定义 Django Allauth 表单中设置密码字段的 help_text?
- terraform - terraform cloud - 已计划但未显示可应用的选项
- linker - 在调试部分周围添加符号会导致二进制文件的大小增加三倍
- php - 如何解决不存在的目标类?
- android - 弹出回栈会引发“已添加片段”异常
- siddhi - 是否可以在 WSO2SP 中生成和使用动态 URL?
- spring - 从外部文件加载 Spring Boot 应用程序属性
- c# - DataTable和Sql server之间的数据传输