gpt4 book ai didi

javascript - 错误 : Actions must be plain objects. 在删除按钮中使用自定义中间件进行异步操作?

转载 作者:行者123 更新时间:2023-12-03 01:18:21 25 4
gpt4 key购买 nike

我试图在用户从列表中删除文件后获取 react 操作来获取文件列表。

在 App.js 中,我将 handleClick 函数传递给嵌套组件。

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

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

我想在删除操作完成后触发请求以从 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)))
};

但是我收到以下错误

Error: Actions must be plain objects. Use custom middleware for async actions.

实现这个的最佳方法是什么

最佳答案

一个操作将调度另一个操作,但不会调度事件处理函数。

您无需从组件中分派(dispatch)deleteFileById,因为这是在将分派(dispatch)操作的操作中导出的函数。

请删除handleClick中的调度才能工作。

错误:

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

正确的一个:

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

关于 this.props.deleteFileById 不是一个函数。

有多种方法可以访问组件中的操作。下面介绍几种方法

您需要安装 prop-types

npm install -s prop-types

如果您的组件是测试组件,则按如下所示设置 Prop 类型

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

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

Test.propTypes = {
deleteFileById: PropTypes.func
}

如果您使用的是 redux connect 那么

没有 Prop 类型

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

或者

使用内置的 React proptypes,您无需单独安装 prop-types

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

您的代码 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)

调度应该在操作中返回,但不能从组件返回到操作,反之亦然

以下是供您引用的示例操作文件。

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

关于javascript - 错误 : Actions must be plain objects. 在删除按钮中使用自定义中间件进行异步操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51889806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com