如何在 redux 中使用 axios 库将数据发布到 API 服务器
Posted
技术标签:
【中文标题】如何在 redux 中使用 axios 库将数据发布到 API 服务器【英文标题】:How to post data to an API server using axios library in redux 【发布时间】:2018-06-10 08:25:16 【问题描述】:我有一个 redux 表单,我正在从中检索数据并尝试将其发布到我的 API 服务器。我的 redux-form 的代码如下:
import React, Component from 'react';
import Field, reduxForm from 'redux-form';
import Link from 'react-router-dom';
import connect from 'react-redux';
import createPosts from '../actions/posts_action';
class CreatePost extends Component
constructor()
super();
this.state =
selectValue : ''
;
this.renderCategory = this.renderCategory.bind(this);
renderField(field)
return(
<div className="title-design">
<label className="label-design"> field.label </label>
<input
type="text"
className="title-input"
...field.input
/>
<div className="text-help has-danger">
field.meta.touched ? field.meta.error : ''
</div>
</div>
);
renderCategory(field)
return(
<div className="title-design">
<label className="label-design">field.label </label>
<Field name="category" className="title-input" component="select">
<option></option>
<option value="react">React</option>
<option value="redux">Redux</option>
<option value="udacity">Udacity</option>
</Field>
<div className="text-help has-danger">
field.meta.touched ? field.meta.error : ''
</div>
</div>
);
onSubmit(values)
this.props.createPosts(values, () =>
this.props.history.push('/');
);
render()
const handleSubmit = this.props;
return (
<form onSubmit=handleSubmit(this.onSubmit.bind(this))>
<Field
label="Title for Post"
name="title"
component=this.renderField
/>
<Field
label="Post Content"
name="body"
component=this.renderField
/>
<Field
label="Category"
name="category"
component=this.renderCategory
/>
<button type="submit" className="btn btn-primary">Submit</button>
<Link to="/">
<button className="cancel-button">Cancel</button>
</Link>
</form>
);
function validate(values)
const errors = ;
if (!values.title)
errors.title = "Enter a title";
if (!values.body)
errors.body = "Enter some content";
if(!values.category)
errors.category = "Please select a category";
return errors;
export default reduxForm(
validate : validate, //validate
form : 'CreatePostForm'
)(
connect(null, createPosts )(CreatePost)
);
用于向 API 服务器发布数据的Action 创建者是:
//Action Creator for creating posts
export function createPosts(values, callback)
const request = axios.post(`$API/posts`,values,headers)
.then(() => callback());
console.log(request);
return dispatch =>
return request.then((data) =>
dispatch(
type: CREATE_POST,
payload: data
)
)
我用于创建帖子的reducer是:
import _ from 'lodash';
import FETCH_POSTS, FETCH_POST, CREATE_POST from '../actions/posts_action';
export default function(state = , action)
switch (action.type)
case FETCH_POST:
// const post = action.payload.data;
// const newState = ...state, ;
// newState[post.id] = post;
// return newState;
return ...state, [action.payload.id]: action.payload;
case FETCH_POSTS:
return posts: ...state.posts, ...action.payload ;
case CREATE_POST:
return posts: ...state, ...action.payload;
default:
return state;
我的所有减速器组合在一起的索引文件是:
import combineReducers from 'redux';
import PostReducer from './PostsReducer';
import reducer as formReducer from 'redux-form';
import CategoriesReducer from './CategoriesReducer';
const rootReducer = combineReducers(
posts: PostReducer,
categories: CategoriesReducer,
form : formReducer
);
export default rootReducer;
现在我面临的问题是,当我尝试提交表单数据时,出现如下屏幕截图所示的错误:
谁能指导我做错了什么以及如何继续?
EDIT 1 整个项目的代码 index.js 文件如下:
import React from 'react';
import ReactDOM from 'react-dom';
import Provider from 'react-redux';
import createStore, applyMiddleware from 'redux';
import BrowserRouter, Route from 'react-router-dom';
import thunk from 'redux-thunk';
import './index.css';
import App from './App';
import reducers from './reducers/index.js'
import Posts from './components/posts_index';
import CreatePost from './components/new_post';
import PostDetail from './components/post_detail';
import CategoryView from './components/category';
import compose from 'redux';
//const createStoreWithMiddleware = createStore(reducers,applyMiddleware(thunk));
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const createStoreWithMiddleware = createStore(reducers, composeEnhancers(applyMiddleware(thunk)));
ReactDOM.render(
<Provider store=createStoreWithMiddleware>
<BrowserRouter>
<div>
<Route path="/new" component=CreatePost />
<Route path="/posts/:id" component=PostDetail />
<Route exact path="/" component=Posts />
<Route path="/:category/posts" component=CategoryView />
</div>
</BrowserRouter>
</Provider> , document.getElementById('root'));
编辑 2:
我还在下面添加 API 服务器的文件:
const clone = require('clone')
let db =
const defaultData =
"8xf0y6ziyjabvozdd253nd":
id: '8xf0y6ziyjabvozdd253nd',
timestamp: 1467166872634,
title: 'Udacity is the best place to learn React',
body: 'Everyone says so after all.',
author: 'thingtwo',
category: 'react',
voteScore: 6,
deleted: false,
commentCount: 2
,
"6ni6ok3ym7mf1p33lnez":
id: '6ni6ok3ym7mf1p33lnez',
timestamp: 1468479767190,
title: 'Learn Redux in 10 minutes!',
body: 'Just kidding. It takes more than 10 minutes to learn technology.',
author: 'thingone',
category: 'redux',
voteScore: -5,
deleted: false,
commentCount: 0
function getData (token)
let data = db[token]
if (data == null)
data = db[token] = clone(defaultData)
return data
function getByCategory (token, category)
return new Promise((res) =>
let posts = getData(token)
let keys = Object.keys(posts)
let filtered_keys = keys.filter(key => posts[key].category === category && !posts[key].deleted)
res(filtered_keys.map(key => posts[key]))
)
function get (token, id)
return new Promise((res) =>
const posts = getData(token)
res(
posts[id].deleted
?
: posts[id]
)
)
function getAll (token)
return new Promise((res) =>
const posts = getData(token)
let keys = Object.keys(posts)
let filtered_keys = keys.filter(key => !posts[key].deleted)
res(filtered_keys.map(key => posts[key]))
)
function add (token, post)
return new Promise((res) =>
let posts = getData(token)
posts[post.id] =
id: post.id,
timestamp: post.timestamp,
title: post.title,
body: post.body,
author: post.author,
category: post.category,
voteScore: 1,
deleted: false,
commentCount: 0
res(posts[post.id])
)
function vote (token, id, option)
return new Promise((res) =>
let posts = getData(token)
post = posts[id]
switch(option)
case "upVote":
post.voteScore = post.voteScore + 1
break
case "downVote":
post.voteScore = post.voteScore - 1
break
default:
console.log(`posts.vote received incorrect parameter: $option`)
res(post)
)
function disable (token, id)
return new Promise((res) =>
let posts = getData(token)
posts[id].deleted = true
res(posts[id])
)
function edit (token, id, post)
return new Promise((res) =>
let posts = getData(token)
for (prop in post)
posts[id][prop] = post[prop]
res(posts[id])
)
function incrementCommentCounter(token, id, count)
const data = getData(token)
if (data[id])
data[id].commentCount += count
module.exports =
get,
getAll,
getByCategory,
add,
vote,
disable,
edit,
getAll,
incrementCommentCounter
【问题讨论】:
【参考方案1】:更新:为动作创建者尝试这种格式。 :
export function createPosts(values, callback)
return dispatch => //return function
return axios.post(`$API/posts`,values,headers) //return post request response
.then((data) => //pass data in as a parameter, call the callback, dispatch the action.
callback();
dispatch(
type: CREATE_POST,
payload: data
)
)
【讨论】:
感谢您的回复。但我已经在使用 redux-thunk。我已将上面 index.js 的代码粘贴到编辑中,显示使用 redux-thunk 文件。你能有吗看看? 当然,给我几分钟。我会试一试,然后告诉你。 数据现在已经发布到服务器了。但是还有一个问题。如果我输入2组数据,即当我第二次尝试输入数据时,以前的数据被删除了,只剩下新的数据。为什么会这样? 我还在用户发布的帖子的编辑中添加了我的服务器文件。请查看该文件是否需要解决上述问题。我无法弄清楚如何进行。 好的,将打开一个新问题并为您提供链接。您能帮我解决这个问题吗。感谢您在解决此问题方面提供的帮助。以上是关于如何在 redux 中使用 axios 库将数据发布到 API 服务器的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 redux 和 redux-promise 将多个 axios 调用合并到一个有效负载中?