当前位置:  开发笔记 > 编程语言 > 正文

使用redux-form和Fetch API进行服务器验证

如何解决《使用redux-form和FetchAPI进行服务器验证》经验,为你挑选了1个好方法。

如何使用redux-form和Fetch API 进行服务器端验证?文档中提供了" 提交验证 "演示,其中说服务器端验证的推荐方法是从onSubmit函数返回一个promise.但是我应该把这个承诺放在哪里?据我所知,onSubmit函数应该是我的动作.

...

this.props.addWidget实际上是我的行动,如下所示.

import fetch from 'isomorphic-fetch';
...
function fetchAddWidget(widget, workspace) {
    return dispatch => {
        dispatch(requestAddWidget(widget, workspace));
        return fetch.post(`/service/workspace/${workspace}/widget`, widget)
            .then(parseJSON)
            .then(json => {
                dispatch(successAddWidget(json, workspace));
                DataManager.handleSubscribes(json);
            })
            .catch(error => popupErrorMessages(error));
    }
}

export function addWidget(data, workspace) {
    return (dispatch, getState) => {
        return dispatch(fetchAddWidget(data, workspace));
    }
}

如您所见,我使用fetch API.我期望fetch将返回promise并且redux-form将捕获它但是这不起作用.如何使它与示例中的承诺一起工作?

同样从演示中我无法理解this.props.handleSubmit函数应该提供什么.对我来说,演示不解释这一部分.



1> ptim..:

以下是我根据http://erikras.github.io/redux-form/#/examples/submit-validation上的示例使用fetch的看法.

......但我应该把这个承诺放在哪里?

...应该在this.props.handleSubmit中提供什么?

详情见下面的评论; 抱歉代码块需要一点滚动才能读取:/


components/submitValidation.js

import React, { Component, PropTypes } from 'react';
import { reduxForm } from 'redux-form';
import { myHandleSubmit, show as showResults } from '../redux/modules/submission';

class SubmitValidationForm extends Component {
  // the following three props are all provided by the reduxForm() wrapper / decorator
  static propTypes = {
    // the field names we passed in the wrapper;
    // each field is now an object with properties:
    // value, error, touched, dirty, etc
    // and methods onFocus, onBlur, etc
    fields: PropTypes.object.isRequired,

    // handleSubmit is _how_ to handle submission:
    // eg, preventDefault, validate, etc
    // not _what_ constitutes or follows success or fail.. that's up to us

    // I must pass a submit function to this form, but I can either:

    // a) import or define a function in this component (see above), then: 
    //   ``, or

    // b) pass that function to this component as 
    //   ``, then 
    //   ``
    handleSubmit: PropTypes.func.isRequired,

    // redux-form listens for `reject({_error: 'my error'})`, we receive `this.props.error`
    error: PropTypes.string
  };

  render() {
    const { fields: { username, password }, error, handleSubmit } = this.props;

    return (
      

        
        {
            // this can be read as "if touched and error, then render div"
            username.touched && username.error && 
{ username.error }
} { password.touched && password.error &&
{ password.error }
} { // this is the generic error, passed through as { _error: 'something wrong' } error &&
{ error }
} // not sure why in the example @erikras uses // `onClick={ handleSubmit }` here.. I suspect a typo. // because I'm using `type="submit"` this button will trigger onSubmit ); } } // this is the Higher Order Component I've been referring to // as the wrapper, and it may also be written as a @decorator export default reduxForm({ form: 'submitValidation', fields: ['username', 'password'] // we send only field names here })(SubmitValidationForm);

../redux/modules/submission.js

// (assume appropriate imports)

function postToApi(values) {
  return fetch( API_ENDPOINT, {
    credentials: 'include',
    mode: 'cors',
    method: 'post',
    body: JSON.stringify({values}),
    headers: {
      'Content-Type': 'application/json',
      'X-CSRFToken': CSRF_TOKEN
    }
  }).then( response => Promise.all([ response, response.json()] ));
}

export const myHandleSubmit = (values, dispatch) => {
  dispatch(startLoading());

  return new Promise((resolve, reject) => {
    // postToApi is a wrapper around fetch
    postToApi(values)
      .then(([ response, json ]) => {
        dispatch(stopLoading());

        // your statuses may be different, I only care about 202 and 400
        if (response.status === 202) {
          dispatch(showResults(values));
          resolve();
        }
        else if (response.status === 400) {
          // here I expect that the server will return the shape:
          // {
          //   username: 'User does not exist',
          //   password: 'Wrong password',
          //   _error: 'Login failed!'
          // }
          reject(json.errors);
        }
        else {
          // we're not sure what happened, but handle it:
          // our Error will get passed straight to `.catch()`
          throw(new Error('Something went horribly wrong!'));
        }
      })
      .catch( error => {
        // Otherwise unhandled server error
        dispatch(stopLoading());
        reject({ _error: error });
      });
  });
};

如果我错过了某些内容/误解等,请填写评论,我会修改:)

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有