Redux-Saga 以某种方式在不经过 saga 的情况下进行 reducer 更新

Redux-Saga somehow reducer updates without going through the saga

我是传奇世界的新手。虽然我在 react-native 领域与 thunk 合作过,但我现在很困惑。我正在努力让我的项目的骨架继续运行,我希望它很快就会变得非常大。考虑到这一点,我试图将逻辑分成多个文件。

我已经让减速器启动了,只是这不是我想要的方式。我不确定它是怎么发生的。我的传奇没有触发,但我的状态更新了。我从我的 reducer 中看到了控制台日志,但没有从 saga watcher 函数中看到任何内容。我应该改变什么?

Index.js

import React from 'react'
import { render } from 'react-dom'
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'
import { Provider } from 'react-redux'

import reducer from './reducers'
import rootSaga from './sagas'
import App from './App'

const sagaMiddleware = createSagaMiddleware()
const store = createStore( 
  reducer,
  applyMiddleware(sagaMiddleware)
)
sagaMiddleware.run(rootSaga)

render( 
  <Provider store={store}>
    <App /> 
  </Provider>, 
  document.getElementById("etlRootDiv"),
);

App.js

import React, { Component } from 'react'
import { connect } from 'react-redux'

import FileExtensionSelector from './components/FileExtensionSelector'
import { setFileExtension } from './actions'

class App extends Component {
  constructor(props) {
    super(props) 
  }

  handleTypeSelect() {
    console.log('handle more click'); 
    this.props.setFileExtension('zip');
    console.log(this.props);
  }

  componentWillReceiveProps(nextProps){
    console.log(nextProps);
  }

  render() {
    return (
      <div>
        <FileExtensionSelector onFileTypeSelect={this.handleTypeSelect.bind(this)} />
        <div>{this.props.fileType} ...asdasd</div>
      </div>
    )
  }
} 

const mapStateToProps = ({ metaState }) => {
  const { fileType } = metaState;
  return { fileType };
};
 
const mapDispatchToProps = (dispatch) => ({
  setFileExtension(ext) {
    dispatch(setFileExtension(ext))
  }
})

export default connect(mapStateToProps, mapDispatchToProps)(App)

reducers/index.js

import { combineReducers } from 'redux';
import metaState from './MetaStateReducer';
 
const rootReducer = combineReducers({
  metaState,
})

export default rootReducer

reducers/metastatereducer.js

const INITIAL_STATE = {
  fileType: null,
  hasHeader: false,
};


export default function (state = INITIAL_STATE, action) {
  switch (action.type) {
    case 'SET_FILE_EXTENSION':
      console.log('/// in set file reducer ///');
      console.log(action);
      // console.log({ ...state, ...INITIAL_STATE, fileType: action.payload });
      return { ...state,...INITIAL_STATE, fileType: action.payload };
    default:
      return state;
  }
}

actions/metaStateActions.js

function action(type, payload = {}) {
  return { type, ...payload }
}

export const SET_FILE_EXTENSION = "SET_FILE_EXTENSION"; 
export const setFileExtension = (extension) => action( SET_FILE_EXTENSION, { payload: extension });

actions/index.js

export { setFileExtension, SET_FILE_EXTENSION } from './metaDataActions';

sagas/metastatesagas.js

import { take, put } from 'redux-saga/effects'
import { SET_FILE_EXTENSION } from '../actions';

function* watchFileExtension(ext) {
  console.log(' --- in watch file ext ---');
  const { extension } = yield take(SET_FILE_EXTENSION)
  console.log(`set extension is ${extension}`);
  // yield put({ type: 'SET_FILE_EXTENSION', payload: ext }); 
}


export const metaStateSagas = [
  take("SET_FILE_EXTENSION", watchFileExtension),
]

sagas/index

import { all } from 'redux-saga/effects'

import { metaStateSagas } from './MetaStateSagas';

export default function* rootSaga() {
  yield all([
    ...metaStateSagas,
  ])
}

redux-saga 总是在尝试处理自身之前将一个动作传递给商店。因此,reducers 总是 运行 在任何 saga 行为执行之前。

认为错误是你的metaStateSagas数组需要使用takeEvery,而不是take,但我并不完全当然。试试看它是否能解决问题。