【问题标题】:Async with redux works? But still gives error, should I ignore it?与 redux 异步工作?但仍然报错,我应该忽略它吗?
【发布时间】:2018-10-09 10:02:39
【问题描述】:

我正在使用 laravel 的混合,react.

正在尝试实现 redux-thunk 中间件。 我遇到了异步调用的问题。 我想将 jquery 用于 ajax(它成功地检索了 API 数据,但我收到一个错误消息,

"Error: dispatch is not a function",意思是我不能对 store 做任何修改。据我了解,调度和 GetState 是通过 thunk 中间件传递的。对吗?那为什么我不能使用这个功能呢?

它还给我一个错误,上面写着:“错误:动作可能没有未定义的“类型”属性。你拼错了一个常量吗?”

在尝试处理上述问题后出现的另一个问题是:“错误:操作必须是普通对象。使用自定义中间件进行异步操作。”

我已经阅读了许多类似的问题,但我似乎仍然无法让它发挥作用。

“操作必须是普通对象。使用自定义中间件进行异步操作。”

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'
import FilterBar from './SideBar/FilterBar';
import Store from '../redux/store/mainStore';
import { REMOVE_ATTRIBUTE_FILTER,ADD_ATTRIBUTE_TO_FILTER, removeAttribute } from '../redux/actions/actions';

Store.subscribe(()=>{
    console.log("store changes", Store.getState())
})



console.log(Store.getState());

Store.dispatch({
type:ADD_ATTRIBUTE_TO_FILTER,
payload:{'make':23}

})


if (document.getElementById('InventoryDisplay')) {
  
        
    ReactDOM.render(
        <Provider store={Store}>
        <FilterBar/>
        </Provider>
        ,document.getElementById('FilterBar'));

   
}

mainstore.js

```

import { createStore,applyMiddleware,combineReducers,compose } from 'redux';
import thunk from 'redux-thunk';
import {inventoryFilter,availableAttributes} from '../reducers/reducer';


const Store = createStore(

///combine imported reducers
    combineReducers({
    activeFilter:inventoryFilter,
    availableAttributes:availableAttributes

},
///initilize store
{},


applyMiddleware(thunk)


));



export default Store;
 

```

actions.js 什么是相关的

```

///first case
const getAttributes2 = (dispatch) => {
  return(
    $.ajax('/getFilteredAttributes/', {
        type: 'GET',
        dataType : 'json'
    }).done(response => {
        dispatch(addAttribute("make",32));
    }).fail((xhr, status, error) => {
        console.log("failed");
    })
  )

};

///second case
const getAttributes = (dispatch) => {
  return ()=>{}

}


export {
  ADD_ATTRIBUTE_TO_FILTER,addAttribute,
  REMOVE_ATTRIBUTE_FILTER,removeAttribute,
  GET_INVENTORY,getInventory,
  GET_AVAILABLE_ATTRIBUTES,getAttributes,
  

}

```

组件连接以存储该调度操作

```

import React from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import * as ActionCreators from '../../../redux/actions/actions';

class DropDownList extends React.Component{
    componentDidMount(){
        this.props.addAttributes("make",32)
        this.props.getAttributes()
        this.props.removeAttributes("make",32)
            

    }
    render(){
  
        return(
        
            <div>
            </div>

        )




        
    }






    
}





function mapStatesToProps(state){
   return{
    activeFilters:state.activeFilter,
    availableAttributes:state.availableAttributes
   } 
};

const mapDispatchToProps = dispatch => {
    return {
        addAttributes: (type,value) => {
            dispatch(ActionCreators.addAttribute(type,value))
          },
        removeAttributes: (type,value) => {
            dispatch(ActionCreators.removeAttribute(type,value))
          },
        getAttributes: () => {
            dispatch(ActionCreators.getAttributes())
          }
    }
}

DropDownList.propTypes = {
    availableAttributes: PropTypes.object.isRequired,
    activeFilters: PropTypes.object.isRequired,
  }
export default connect(mapStatesToProps,mapDispatchToProps)(DropDownList)

```

对于第二个错误的情况一,我的解决方案是将 ajax 函数调用放入包含“type”属性的对象中。像这样的

return (

  {
    type: "Something",


    $.ajax('/getFilteredAttributes/', {
      type: 'GET',
      dataType: 'json'
    }).done(response => {
      dispatch(addAttribute("make", 32));
    }).fail((xhr, status, error) => {
      console.log("failed");
    })

  })

进行了 ajax 调用,但调度仍然不可用,我迷路了,正在寻找最佳解决方案?也许我想太多了,或者错过了一个小细节。我尝试了其他解决方案,但没有一个对我有用。

请帮忙。

【问题讨论】:

    标签: javascript jquery reactjs redux redux-thunk


    【解决方案1】:

    很难确切地知道发生了什么,但我绝对不建议您忽略/破解您在使用流行库的常见功能时遇到的错误。为了简单起见,正确实施非常重要。

    在我看来,您使用 thunk 的方式有点奇怪。 您调度的操作返回的函数有 dispatch 和 getState 作为参数:

    在您的情况下,您的 thunk 操作可能如下所示

    在你的 actions.js 中:

    export function getAttributes2(){
      return function(dispatch, getState){
        // you could dispatch a fetching action here before requesting!
        return $.ajax('/getFilteredAttributes/', {type: 'GET', dataType: 'json'})
          .done(response => dispatch(saveTheResponseAction(response)))
          .fail((xhr, status, error) => console.log("failed"))
    }
    

    将该 thunk 函数映射到您的道具:

    import {getAttributes2} from '../../../redux/actions/actions';
    
    const mapDispatchToProps = dispatch => {
      return {
        getAttributes2: () => dispatch(getAttributes2()),
      }
    }
    

    这样你可以从你的 api 调用的 .done 部分派发一个动作,你可以响应错误,你甚至可以在返回你的 api 调用之前派发一个动作,让 redux 知道你已经请求但还没有收到数据,可以做各种加载状态。

    希望对你有帮助,告诉我:)

    【讨论】:

    • 不,目前的错误是:动作必须是普通对象。使用自定义中间件进行异步操作。
    • 好的,我猜你设置中间件的方式一定有问题。您能否设置一个简单的 CRA 项目并检查您是否可以先在一个非常简单的环境中启动并运行。
    • 是的,实际中间件的设置在 mainstore.js 中。我只是按照教程进行操作,我不知道为什么我无法运行调度功能或 thunk 是否正常运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 2020-07-27
    相关资源
    最近更新 更多