简体   繁体   English

错误:动作必须是普通对象。 在删除按钮中将自定义中间件用于异步操作?

[英]Error: Actions must be plain objects. Use custom middleware for async actions, in a delete button?

I am trying to get a react action to fetch a list of files after the user deletes a file from the list. 我试图在用户从列表中删除文件后获取一个反应操作来获取文件列表。

In App.js I pass a handleClick function to the nested component. 在App.js中,我将handleClick函数传递给嵌套组件。

App.js App.js

    class App extends Component {
    static propTypes = {
        files: PropTypes.array.isRequired,
        isFetching: PropTypes.bool.isRequired,
        dispatch: PropTypes.func.isRequired,
        handleClick : PropTypes.func
    };

    componentDidMount() {
        const {dispatch} = this.props;
        dispatch(fetchFiles);
    }

    handleClick = fileId => {
        const {dispatch} = this.props;
        deleteFileById(dispatch,fileId);
    };

    render() {
        const {files, isFetching, dispatch} = this.props;
        const isEmpty = files.length === 0;
        return (
            <div>
                <h1>Uploadr</h1>
                {isEmpty
                    ? (isFetching ? <h2>Loading...</h2> : <h2>No files.</h2>)
                    : <div style={{opacity: isFetching ? 0.5 : 1}}>
                        <Files files={files} handleClick={this.handleClick}/>
                    </div>
                }
            </div>
        )
    }
}

const mapStateToProps = state => {
    const {isFetching, items: files} = state.files;

    return {
        files,
        isFetching,
    }
};


export default connect(mapStateToProps)(App)

Files.js Files.js

import React from 'react'
import PropTypes from 'prop-types'

const Files = ({files, handleClick }) => (
    <ul>
        {files.map((file, i) =>
            <li key={i}>{file.name}
                <button onClick={() => (handleClick(file.id))}>Delete</button>
            </li>
        )}
    </ul>
);

Files.propTypes = {
    files: PropTypes.array.isRequired,
    handleClick: PropTypes.func.isRequired
};

export default Files

actions.js actions.js

I am wanting to trigger a request to get a new list of files from the API after the delete action is done. 我想在完成删除操作后触发一个从API获取文件新列表的请求。

export const deleteFileById = (dispatch, fileId) => {
    dispatch(deleteFile);
    return fetch(`/api/files/${fileId}`, {method : 'delete'})
        .then(dispatch(fetchFiles(dispatch)))
};

export const fetchFiles = (dispatch) => {
    dispatch(requestFiles);
    return fetch('/api/files')
        .then(response => response.json())
        .then(json => dispatch(receiveFiles(json)))
};

However I am getting the following error 但是我收到以下错误

Error: Actions must be plain objects. 错误:动作必须是普通对象。 Use custom middleware for async actions. 使用自定义中间件进行异步操作。

What is the best way to implement this 什么是实现这一目标的最佳方法

An action will dispatch another action but not event handler function. 一个动作将调度另一个动作,而不是事件处理函数。

You no need to dispatch deleteFileById from component because this is a function exported in actions which will dispatch an action. 您无需从组件分派deleteFileById,因为这是在操作中导出的函数,该功能将分派操作。

Please remove dispatch in handleClick to work. 请删除handleClick中的调度以工作。

Wrong one: 错误之一:

handleClick = fileId => {
    this.props.deleteFileById(dispatch(this.props.dispatch,fileId));
};

Correct one: 正确的一个:

handleClick = fileId => {
    this.props.deleteFileById(this.props.dispatch,fileId);
};

Regarding this.props.deleteFileById is not a function. 关于this.props.deleteFileById不是一个函数。

There are many ways to access actions in your component. 有很多方法可以访问组件中的操作。 Below are few ways 以下是几种方法

You need to install prop-types 您需要安装道具类型

npm install -s prop-types npm install -s道具类型

If your component is Test then set prop types as like below 如果您的组件是Test,则按如下所示设置prop类型

import PropTypes from 'prop-types';
import React, {Component} from 'react';

class Test extends Component{
    render(){
      return(
        <div</div>
      )
    }
}

Test.propTypes = {
  deleteFileById: PropTypes.func
}

If you are using redux connect then 如果您使用redux connect然后

Without prop-types 没有道具

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../actions';

class Test extends Component{
        render(){
          return(
            <div</div>
          )
        }
    }

export default connect(null, {...actions})(Test);

OR 要么

With inbuilt react proptypes you no need to install prop-types separately 使用内置的React Protype,您无需单独安装prop-type

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../actions';
import {push} from 'react-router-redux';

class Test extends Component{
static get propTypes() {
    return { 
      sendContactForm: React.PropTypes.func
    }
  }
        render(){
          return(
            <div</div>
          )
        }
    }

const actionsToProps = {
      deleteFileById: actions.deleteFileById,
      push
    }

export default connect(null, actionsToProps)(Test);

Your code App.jsx should be something like below 您的代码App.jsx应该如下所示

class App extends Component {
    static propTypes = {
        files: PropTypes.array.isRequired,
        isFetching: PropTypes.bool.isRequired,
        deleteFileById : PropTypes.func,
        fetchFiles: PropTypes.func
    };

    componentDidMount() {
       this.props.fetchFiles();
    }

    handleClick = fileId => {
        this.props.deleteFileById(fileId);
    };

    render() {
        const {files, isFetching} = this.props;
        const isEmpty = files.length === 0;
        return (
            <div>
                <h1>Uploadr</h1>
                {isEmpty
                    ? (isFetching ? <h2>Loading...</h2> : <h2>No files.</h2>)
                    : <div style={{opacity: isFetching ? 0.5 : 1}}>
                        <Files files={files} handleClick={this.handleClick}/>
                    </div>
                }
            </div>
        )
    }
}

const mapStateToProps = state => {
    const {isFetching, items: files} = state.files;

    return {
        files,
        isFetching,
    }
};


export default connect(mapStateToProps)(App)

dispatch should be returned in actions but not from component to actions or vice versa 调度应在操作中返回,而不是在组件之间返回,反之亦然

Below is sample action file for your ref. 以下是供您参考的示例操作文件。

import ajax from '../ajax';
import {Map, fromJS} from 'immutable';
import config from '../config';
import {push} from 'react-router-redux'

export const URL_PREFIX = 'http://localhost:3000/api';

export const SEND_CONTACT_FORM_REQUEST = 'SEND_CONTACT_FORM_REQUEST';
export const SEND_CONTACT_FORM_SUCCESS = 'SEND_CONTACT_FORM_SUCCESS';
export const SEND_CONTACT_FORM_ERROR = 'SEND_CONTACT_FORM_ERROR';


export function sendContactFormRequest(){
  return {
    type: SEND_CONTACT_FORM_REQUEST,
    loading: true
  }
}

export function sendContactFormSuccess(data){
  return {
    type: SEND_CONTACT_FORM_SUCCESS,
    loading: false,
    data: data
  }
}

export function sendContactFormError(errors){
  return {
    type: SEND_CONTACT_FORM_ERROR,
    loading: false,
    errors: errors
  }
}



export function sendContactForm(firstName, lastName, email, subject, message) {
  return dispatch => {
    dispatch(sendContactFormRequest());
    return ajax.post(URL_PREFIX + '/communication/contact', { firstName, lastName, email, subject, message })
      .then(res => {
        dispatch(sendContactFormSuccess(res.data))


      })
      .catch(errors => {
        dispatch(sendContactFormError(errors))
      })
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 异步操作 Redux 未处理拒绝(错误):操作必须是普通对象。 使用自定义中间件进行异步操作 - Async Action Redux Unhandled Rejection (Error): Actions must be plain objects. Use custom middleware for async actions 错误服务器错误:操作必须是普通对象。 使用自定义中间件进行异步操作 - Error server Error: Actions must be plain objects. Use custom middleware for async actions 错误:动作必须是普通对象。 使用自定义中间件进行异步操作。 React-redux错误 - Error: Actions must be plain objects. Use custom middleware for async actions. React-redux error 错误 - 操作必须是普通对象。 使用自定义中间件进行异步操作 - Error - Actions must be plain objects. Use custom middleware for async actions React-Redux:动作必须是普通对象。 使用自定义中间件进行异步操作错误 - React-Redux: Actions must be plain objects. Use custom middleware for async actions Error react-redux 错误:操作必须是普通对象。 使用自定义中间件进行异步操作 - react-redux Error: Actions must be plain objects. Use custom middleware for async actions 这个错误信息有什么用? 动作必须是普通对象。 使用自定义中间件进行异步操作 - what is this error message for ? Actions must be plain objects. Use custom middleware for async actions React Native 和 Redux - 错误:操作必须是普通对象。 使用自定义中间件进行异步操作 - React Native & Redux - Error: Actions must be plain objects. Use custom middleware for async actions 如何修复:错误:操作必须是普通对象。 使用自定义中间件进行异步操作。? - How to fix: Error: Actions must be plain objects. Use custom middleware for async actions.? Typescript、React 和 Redux axios 错误 - 操作必须是普通对象。 使用自定义中间件进行异步操作 - Typescript, React and Redux axios Error - actions must be plain objects. use custom middleware for async actions
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM