发布到 mongoDB 与 redux/redux-thunk 互动

Posting to mongoDB in react with redux/redux-thunk

模拟库 显示数据库中的书籍(作者标题流派)以及添加书籍的能力。

正在从我的 React 组件中正确获取数据。
数据以实物形式传递给我的 action creator,同样由 reducer 正确处理。
似乎我的异步 thunk 已正确设置为使用 axios 发出 post 请求。我正在通过获取请求正确获取数据库中已有的书籍。

我的路线似乎有效,因为我能够使用 postman 正确添加一本书并获取所有书籍。再一次,从我的反应组件中获取时,我的书可以正确显示。

问题出在哪里?为什么我的 post 请求没有到达我的数据库?

我的行为--

export const fetchBooks = () => dispatch => {
    axios.get('/books')
        .then(res => dispatch({
            type: FETCH_BOOKS,
            payload: res.data
        })) 
}

export const addBook = ({ title, author, genre}) => dispatch => {
    dispatch(addBookStarted())
    axios
      .post('/books', {
        title, 
        author, 
        genre
      })
      .then(res => {
        dispatch(addBookSuccess(res.data))
      })
      .catch(err => {
          dispatch(addBookFailure(err.message))
      })
}


const addBookSuccess = book => ({
    type: ADD_BOOK_SUCCESS,
    payload: {
      ...book
    }
});

const addBookStarted = () => ({
    type: ADD_BOOK_STARTED
});

我的减速器--

const initialState = {
    books: [],
    error: null,
    loadinng: false
}

export default function(state = initialState, action) {
    switch(action.type) {
        case FETCH_BOOKS:
            return {
                ...state,
                books: action.payload
            }

        case ADD_BOOK_STARTED:
            return {
                ...state,
                loading: true
            }

        case ADD_BOOK_SUCCESS:
            return {
                ...state,
                loading: false,
                error: null,
                books: [...state.books, action.payload]
            }

        case ADD_BOOK_FAILURE:
            return {
                ...state,
                loading: false,
                error: action.payload.error
            }

        default: 
            return state
    }
}

错误--

{ ValidationError: book validation failed: title: Path `title` is required., aut
hor: Path `author` is required., genre: Path `genre` is required.
    at ValidationError.inspect (C:\Users\Leeko\documents\repos\libapp\backend\no
de_modules\mongoose\lib\error\validation.js:59:24)
    at formatValue (internal/util/inspect.js:526:31)
    at inspect (internal/util/inspect.js:194:10)
    at Object.formatWithOptions (util.js:90:12)
    at Console.(anonymous function) (console.js:204:15)
    at Console.warn (console.js:221:31)
    at b.save.then.catch.err (C:\Users\Leeko\documents\repos\libapp\backend\serv
er.js:34:31)
    at process.internalTickCallback (internal/process/next_tick.js:77:7)
  errors:
   { title:
      { ValidatorError: Path `title` is required.
          at new ValidatorError (C:\Users\Leeko\documents\repos\libapp\backend\n
ode_modules\mongoose\lib\error\validator.js:29:11)
          at validate (C:\Users\Leeko\documents\repos\libapp\backend\node_module
s\mongoose\lib\schematype.js:926:13)
          at C:\Users\Leeko\documents\repos\libapp\backend\node_modules\mongoose
\lib\schematype.js:979:11
          at Array.forEach (<anonymous>)
          at SchemaString.SchemaType.doValidate (C:\Users\Leeko\documents\repos\
libapp\backend\node_modules\mongoose\lib\schematype.js:935:19)
          at C:\Users\Leeko\documents\repos\libapp\backend\node_modules\mongoose
\lib\document.js:1941:9
          at process.internalTickCallback (internal/process/next_tick.js:70:11)
        message: 'Path `title` is required.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'title',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true },

sever.js(路线)

const mongoose    = require("mongoose");
const express     = require("express");
const bodyParser  = require("body-parser");

const db          = require('./config/db');

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

const app         = express();

app.use(bodyParser.urlencoded({extended: true}));

app.route('/books')
    .get((req, res) => {
        Book.find({}).then(docs => res.json(docs))
    })
    .post((req, res) => {
        let b = new Book({
            title: req.body.title,
            author: req.body.author,
            genre: req.body.genre
        })

        b.save()
            .then(doc => console.log(doc))
            .catch(err => console.error(err))
        res.json(req.body)
    })

书本模型

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

const BookSchema = new Schema({
    title: {
        type: String,
        // required: true,
        lowercase: true
    },
    author: {
        type: String,
        // required: true,
        lowercase: true
    },
    genre: {
        type: String,
        // required: true,
        lowercase: true
    },
    pages: {
        type: Number
    },
    available: {
        type: Boolean,
        default: true
    }
});

module.exports = Book = mongoose.model('book', BookSchema);

您可能需要在 axios 设置中支持完整的 url 主机,还请 post 上下文错误日志

axios 调用的一个小改动

axios
      .post('/books', {
        'title':title, 
        'author':author, 
        'genre':genre
      })
      .then(res => {
        dispatch(addBookSuccess(res.data))
      })
      .catch(err => {
          dispatch(addBookFailure(err.message))
      })

post 请求需要键值正文解析器

在我的 server.js 中,我遗漏了以下内容:

...
app.use(bodyParser.json());
...