У меня проблема " Действия должны быть простыми объектами. Используйте пользовательское промежуточное ПО для асинхронных действий. "
Я использую реагирование с этим образцом (https://github.com/react-boilerplate/react-boilerplate/)
Я трачу 1 день, чтобы решить эту проблему, но безрезультатно. Я пытался переместить запрос на выборку к действию (без саги) и результат тот же.
Мой компонент:
...
import { compose } from 'redux';
import injectReducer from 'utils/injectReducer';
import injectSaga from 'utils/injectSaga';
import { successFetching } from './actions';
import reducer from './reducers';
import saga from './saga';
class NewsListPage extends React.PureComponent {
componentDidMount() {
const { dispatch } = this.props
dispatch(saga())
}
...
};
NewsListPage.propTypes = {
isFetching: PropTypes.bool.isRequired,
isSuccess: PropTypes.bool.isRequired,
items: PropTypes.array.isRequired,
dispatch: PropTypes.func.isRequired,
}
const selector = (state) => state;
const mapStateToProps = createSelector(
selector,
(isFetching, isSuccess, items) => ({ isFetching, isSuccess,items })
);
function mapDispatchToProps(dispatch) {
return {
dispatch,
};
}
const withReducer = injectReducer({ key: 'NewsList', reducer });
const withSaga = injectSaga({ key: 'NewsList', saga });
const withConnect = connect(mapStateToProps, mapDispatchToProps);
export default compose(
withReducer,
withSaga,
withConnect
)(NewsListPage);
Мои действия:
export const NEWS_FETCH_LOADING = 'NEWS_FETCH_LOADING';
export const NEWS_FETCH_FAILURE = 'NEWS_FETCH_FAILURE';
export const NEWS_FETCH_SUCCESS = 'NEWS_FETCH_SUCCESS';
export function preFetching() {
return {
type: NEWS_FETCH_LOADING,
}
}
export function successFetching(json) {
return {
type: NEWS_FETCH_SUCCESS,
payload: json
}
}
export function failureFetching(error) {
return {
type: NEWS_FETCH_FAILURE,
payload: error
}
}
Мои редукторы:
...
import { NEWS_FETCH_LOADING, NEWS_FETCH_FAILURE, NEWS_FETCH_SUCCESS } from './actions'
const INITIAL_STATE = {
isFetching: false,
isSuccess: false,
items: []
};
function NewsListReducer(state = INITIAL_STATE, action) {
switch (action.type) {
case NEWS_FETCH_LOADING:
case NEWS_FETCH_FAILURE:
return Object.assign({}, state, {
isFetching: true,
isSuccess: false
})
case NEWS_FETCH_SUCCESS:
return Object.assign({}, state, {
isFetching: false,
isSuccess: true,
items: action.payload,
})
default:
return Object.assign({}, state)
}
}
export const rootReducer = combineReducers({
NewsListReducer
})
export default rootReducer
Моя сага:
import { call, put, select, takeLatest } from 'redux-saga/effects';
import {NEWS_FETCH_LOADING, NEWS_FETCH_FAILURE, NEWS_FETCH_SUCCESS, preFetching, successFetching, failureFetching} from './actions';
import request from 'utils/request';
export function* getNews() {
const requestURL ='%MY_URL%';
try {
const req = yield call(request, requestURL);
yield put(successFetching(req));
} catch (err) {
yield put(failureFetching(err));
}
}
export default function* NewsListSaga() {
yield takeLatest(NEWS_FETCH_SUCCESS, getNews);
}
EDIT:
@ Аллео Индонг, я попробовал твой совет, и это почти сработало.
Я изменяю в компоненте mapDispatchToProps значение
export function mapDispatchToProps(dispatch) {
return {
getData: () => dispatch(loadNews()),
};
}
И добавить новую функцию в actions.js
export function loadNews() {
return {
type: NEWS_FETCH_SUCCESS,
}
}
Но теперь ajax отправляется каждые секунды , как во время цикла. Я попытался позвонить this.props.getData();
в componentDidMount
и constructor
и результат такой же.
РЕДАКТИРОВАТЬ 2
В компонент добавляю
import * as actionCreators from './actions';
import { bindActionCreators } from 'redux';
В конструкторе я изменяю
constructor(props) {
super(props);
const {dispatch} = this.props;
this.boundActionCreators = bindActionCreators(actionCreators, dispatch)
}
Но здесь dispatch
не определено и в componentDidMount
тоже.
И изменить mapDispatchToProps
на
export function mapDispatchToProps(dispatch) {
return {
...bindActionCreators(actionCreators, dispatch),
};
}