2017-12-30 34 views
3

Ich habe ein Redux-Formular, aus dem ich Daten abrufen und versuchen, es auf meinem API-Server zu veröffentlichen. Der Code für meine Redux-Form ist unten angegeben:Wie man Daten auf einen API-Server mit Axios-Bibliothek in redux

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) 
); 

My Aktion Schöpfer für Daten an den API-Server zu veröffentlichen ist:

//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 
     }) 
    }) 
    } 
} 

Mein Minderer für die Erstellung der Post ist:

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; 
    } 

} 

Meine Index-Datei für alle kombinierten Reduzierungen zusammen ist:

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; 

Nun ist die Frage, die ich ist bin vor, wenn ich versuche, meine Daten zu übermitteln, ich den Fehler wie in der Abbildung unten gezeigt :

error_file

Kann mir jemand bitte leite mit dem, was ich falsch mache und wie es weitergehen?

EDIT 1-Code index.js Datei für das gesamte Projekt ist unten angegeben:

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')); 

Edit 2:

ich die Datei auch für die API-Server unten bin und fügte hinzu:

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 
} 

Antwort

1

Update: Versuchen Sie dieses Format für den Aktionsersteller. :

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 
     }) 
    }) 
    } 
} 
+0

Danke für die reply.But ich schon redux-thunk.I bin mit haben den Code für mein index.js oben in einer Bearbeitung eingefügt whixh die Verwendung von redux-Thunk-Datei zeigt .Can Sie bitte eine haben sieh es dir an? – pranami

+0

Ich habe die Antwort aktualisiert. Lass es mich wissen, wenn es hilft. –

+0

sicher, gib mir ein paar mins.Will es versuchen und lassen Sie es wissen. – pranami

Verwandte Themen