Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 异步redux。错误:修改器可能不会发出操作_Javascript_Reactjs_Redux - Fatal编程技术网

Javascript 异步redux。错误:修改器可能不会发出操作

Javascript 异步redux。错误:修改器可能不会发出操作,javascript,reactjs,redux,Javascript,Reactjs,Redux,我一直遇到一个类似于并行异步redux的错误。在较高的层次上,我尝试调度一组异步操作,从URL获取资产 我最初尝试了redux-thunk中间件,但遇到了相同的错误。此后,我转向了“侦听器”风格的中间件,它看起来像: // listener-middleware.js // taken from https://medium.com/@alexandereardon/the-middleware-listener-pattern-better-asynchronous-actions-in-re

我一直遇到一个类似于并行异步redux的错误。在较高的层次上,我尝试调度一组异步操作,从URL获取资产

我最初尝试了
redux-thunk
中间件,但遇到了相同的错误。此后,我转向了“侦听器”风格的中间件,它看起来像:

// listener-middleware.js
// taken from https://medium.com/@alexandereardon/the-middleware-listener-pattern-better-asynchronous-actions-in-redux-16164fb6186f
export default (...listeners) => store => next => action => {
  // listeners are provided with a picture
  // of the world before the action is applied
  const preActionState = store.getState();

  // release the action to reducers before
  // firing additional actions
  next(action);


  // always async
  setTimeout(() => {
    // can have multiple listeners listening
    // against the same action.type
    listeners.forEach(listener => {
      if (listener[action.type]) {
        listener[action.type](action, store.dispatch, preActionState);
      }
    });
  });
};
import { assetsFetchBinary, assetsReceiveBinary } from '../assets/actions.js';

export default {
  [assetsFetchBinary.toString()]: (action, dispatch, state) => {
    const assetPath = state.config.assetPath + '/' + action.payload.assetName;

    if(!state.assets[action.payload.assetName]){
      fetch(assetPath)
        .then(response => response.arrayBuffer())
        .then(arrayBuffer => {
          return dispatch(assetsReceiveBinary(action.payload.assetName, arrayBuffer))
        });
    }
  },
}
  function dispatch (action) {
    if (!action || !isPlainObject(action)) throw new Error('action parameter is required and must be a plain object')
    if (!action.type || typeof action.type !== 'string') throw new Error('type property of action is required and must be a string')
    if (isEmitting) throw new Error('modifiers may not emit actions')
然后,资产侦听器看起来像:

// listener-middleware.js
// taken from https://medium.com/@alexandereardon/the-middleware-listener-pattern-better-asynchronous-actions-in-redux-16164fb6186f
export default (...listeners) => store => next => action => {
  // listeners are provided with a picture
  // of the world before the action is applied
  const preActionState = store.getState();

  // release the action to reducers before
  // firing additional actions
  next(action);


  // always async
  setTimeout(() => {
    // can have multiple listeners listening
    // against the same action.type
    listeners.forEach(listener => {
      if (listener[action.type]) {
        listener[action.type](action, store.dispatch, preActionState);
      }
    });
  });
};
import { assetsFetchBinary, assetsReceiveBinary } from '../assets/actions.js';

export default {
  [assetsFetchBinary.toString()]: (action, dispatch, state) => {
    const assetPath = state.config.assetPath + '/' + action.payload.assetName;

    if(!state.assets[action.payload.assetName]){
      fetch(assetPath)
        .then(response => response.arrayBuffer())
        .then(arrayBuffer => {
          return dispatch(assetsReceiveBinary(action.payload.assetName, arrayBuffer))
        });
    }
  },
}
  function dispatch (action) {
    if (!action || !isPlainObject(action)) throw new Error('action parameter is required and must be a plain object')
    if (!action.type || typeof action.type !== 'string') throw new Error('type property of action is required and must be a string')
    if (isEmitting) throw new Error('modifiers may not emit actions')
商店配置和applyMiddleware是:

import { createStore, applyMiddleware } from 'minidux'
import rootReducer from './rootReducer';
import { createLogger } from 'redux-logger';
import { routerMiddleware } from 'react-router-redux'
import { sceneTickAction } from './dsl/scene/actions.js';
import assetMiddleware from './dsl/assets/middleware.js';

import listenerMiddleware from './listener-middleware';

const logger = (initialState) => {
  const predicate = (getState, action) => {
    if(action.type === sceneTickAction.toString()){
      return false;
    }
    return true;
  }

  return createLogger({predicate});
};

const getMiddleWare = (initialState, history) => {
  const list = [];

  if(initialState.system.role === 'client'){
    const routerHistory = routerMiddleware(history);

    list.push(routerHistory);
    list.push(listenerMiddleware(assetMiddleware))


  list.push(logger(initialState));

  return list;
};


const configureStore = (initialState, history) => {
  return createStore(
    rootReducer(initialState),
    initialState,
    applyMiddleware.apply(this, getMiddleWare(initialState, history))
  );
}

export default configureStore
行动是直接的

import { createAction } from 'redux-actions';
export const assetsReceiveBinary = createAction('@ASSETS/RECEIVE_BINARY')
export const assetsFetchBinary = createAction('@ASSETS/FETCH_BINARY')
和减速器:

import { handleActions } from 'redux-actions';
import { assetsFetchBinary, assetsReceiveBinary } from '../assets/actions.js';

export const assetReducer = (state, action) => handleActions({
  [assetsFetchBinary]: (state, action) => {
    if(state.assets[action.path]){ return state; }
    return {
      ...state,
      assets: {
        ...state.assets,
        [action.path]: {}
      }
    }
  },

  [assetsReceiveBinary]: (state, action) => {
    return {
      ...state,
      assets: {
        ...state.assets,
        [action.path]: {arrayBuffer: action.arrayBuffer}
      }
    }
  }
}, state)(state, action);

export default assetReducer;
堆栈跟踪如下所示:

createStore.js:27 Uncaught Error: modifiers may not emit actions
    at dispatch (createStore.js:27)
    at listener-middleware.js:10
    at middleware.js:13
    at Object.assetsFetchBinary (bindActionCreators.js:3)
    at CharacterView.jsx:21
    at Array.forEach (<anonymous>)
    at CharacterView.componentDidUpdate (CharacterView.jsx:20)
    at commitLifeCycles (react-dom.development.js:11517)
    at commitAllLifeCycles (react-dom.development.js:12294)
    at HTMLUnknownElement.callCallback (react-dom.development.js:1299)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:1338)
    at invokeGuardedCallback (react-dom.development.js:1195)
    at commitAllWork (react-dom.development.js:12415)
    at workLoop (react-dom.development.js:12687)
    at HTMLUnknownElement.callCallback (react-dom.development.js:1299)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:1338)
    at invokeGuardedCallback (react-dom.development.js:1195)
    at performWork (react-dom.development.js:12800)
    at scheduleUpdateImpl (react-dom.development.js:13185)
    at scheduleUpdate (react-dom.development.js:13124)
    at Object.enqueueSetState (react-dom.development.js:9646)
    at Connect../node_modules/react/cjs/react.development.js.ReactComponent.setState (react.development.js:
该分派调用的
操作
看起来像
{type:@ASSETS/FETCH_BINARY}

此外,我在
componentDidMount
中调用这些操作,如下所示:

class CharacterView extends Component {
  componentDidUpdate(){
    if(this.props.missingItemAssets){
      this.props.missingItemAssets.forEach((assetName) => {
        this.props.assetsFetchBinary(assetName);
      });
    }
  }
如果我将分派调用包装在
0
setTimeout
中,则可以防止出现错误

class CharacterView extends Component {
  componentDidUpdate(){
    if(this.props.missingItemAssets){
      setTimeout(() => {
      this.props.missingItemAssets.forEach((assetName) => {
        this.props.assetsFetchBinary(assetName);
      });
      }, 0)
    }
  }

您提到在
componentDidMount
中分派操作,但您的示例显示您实际上是从
componentdiddupdate
分派操作

class CharacterView extends Component {
  componentDidUpdate(){ // <--- should be componentDidMount?
    if(this.props.missingItemAssets){
      this.props.missingItemAssets.forEach((assetName) => {
        this.props.assetsFetchBinary(assetName);
      });
    }
  }
}
class CharacterView扩展组件{
componentDidUpdate(){//{
this.props.AssetFetchBinary(assetName);
});
}
}
}

假设你在问题中的例子是准确的,这可能会导致你的问题。

可能你正面临着这个问题?我认为更准确。哦,男孩看起来我在
componentdiddupdate
componentdiddemount
中都有调度循环,将其移动到一个有帮助。我想这是造成双重排放的原因