mapDispatchToProps error: component is receiving an object but function expected
mapDispatchToProps error: component is receiving an object but function expected
我对 React 生态系统完全陌生。为了更好地理解 React saga,我创建了一个小项目,它在屏幕上显示一个值,5 秒后它是一个 saga 函数,应该从 useEffect 调用并更改该值。我在 saga 和动作函数中放置了一些日志消息。好像没有调用监听器
constants.js
export const ATTEMPT_DELAY = 'app/SupportPage/ATTEMPT_DELAY';
export const DELAY_SUCCESS = 'app/SupportPage/DELAY_SUCCESS';
export const DELAY_ERROR = 'app/SupportPage/DELAY_SUCCESS';
action.js
import { ATTEMPT_DELAY, DELAY_SUCCESS, DELAY_ERROR } from './constants';
export function attempDelay() {
console.log('attempt delay action called');
return {
type: ATTEMPT_DELAY,
};
}
export function delaySuccess(value) {
console.log('delay success action called');
return {
type: DELAY_SUCCESS,
value,
};
}
export function delayError() {
return {
type: DELAY_ERROR,
};
}
saga.js
import { takeLatest, put } from 'redux-saga/effects';
import { ATTEMPT_DELAY } from './constants';
import { delaySuccess, delayError } from './actions';
export function* delayListener() {
yield takeLatest(ATTEMPT_DELAY, delay);
}
export function* delay() {
console.log('delay saga called')
const value = 10;
try {
yield put(delaySuccess(value));
} catch (e) {
yield put(delayError);
}
}
reducer.js
import produce from 'immer';
import { ATTEMPT_DELAY, DELAY_SUCCESS, DELAY_ERROR } from './constants';
export const initialState = {
value: 5,
isLoading: false,
};
const supportPageReducer = (state = initialState, action) =>
// eslint-disable-next-line no-unused-vars
produce(state, draft => {
// eslint-disable-next-line default-case
switch (action.type) {
case ATTEMPT_DELAY:
draft.isLoading = true;
break;
case DELAY_SUCCESS:
draft.value = action.value || console.log('setting value');
break;
case DELAY_ERROR:
draft.isLoading = false;
break;
default:
break;
}
});
export default supportPageReducer;
index.js
import React, { memo, useEffect } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Helmet } from 'react-helmet';
import { FormattedMessage } from 'react-intl';
import { createStructuredSelector } from 'reselect';
import { compose } from 'redux';
import { useInjectSaga } from 'utils/injectSaga';
import { useInjectReducer } from 'utils/injectReducer';
import makeSelectSupportPage from './selectors';
import reducer from './reducer';
import { delayListener } from './saga';
import { attempDelay } from './actions';
import messages from './messages';
export function SupportPage({ supportPage: { isLoading, value }, delay }) {
useInjectReducer({ key: 'supportPage', reducer });
useInjectSaga({ key: 'supportPage', saga: delayListener });
useEffect(() => {
setTimeout(() => {
console.log('delay called');
delay();
}, 5000);
});
return (
<div>
<Helmet>
<title>SupportPage</title>
<meta name="description" content="Description of SupportPage" />
</Helmet>
<FormattedMessage {...messages.header} />
<h1>{isLoading ? 'loading' : 'not loading'}</h1>
<h1>{value}</h1>
</div>
);
}
SupportPage.propTypes = {
supportPage: PropTypes.object,
delay: PropTypes.func,
};
const mapStateToProps = createStructuredSelector({
supportPage: makeSelectSupportPage(),
});
function mapDispatchToProps(dispatch) {
return {
delay: dispatch(attempDelay()),
};
}
const withConnect = connect(
mapStateToProps,
mapDispatchToProps,
);
export default compose(
withConnect,
memo,
)(SupportPage);
当我在浏览器中打开控制台时,我在从 useEffect 调用 delay() 之前看到了日志,并且出现错误“Uncaught ReferenceError: delay is not defined
at eval” 我试着用谷歌搜索这个错误,但没有得到任何与 redux-saga 相关的信息。
在 运行 项目之后,当我进行更改并点击保存时,我注意到了一些事情,它重建了项目,然后 saga 被调用并且所有日志消息都在那里并且值按预期更改。
不知道怎么回事!!!
我发现了我的错误。
function mapDispatchToProps(dispatch) {
return {
delay: dispatch(attempDelay()),
};
}
这里我调用 dispatch 并将 dispatch 的 return 值映射到 delay 对象。它应该是一个函数。
更正为:
delay: () => dispatch(attempDelay()),
我对 React 生态系统完全陌生。为了更好地理解 React saga,我创建了一个小项目,它在屏幕上显示一个值,5 秒后它是一个 saga 函数,应该从 useEffect 调用并更改该值。我在 saga 和动作函数中放置了一些日志消息。好像没有调用监听器
constants.js
export const ATTEMPT_DELAY = 'app/SupportPage/ATTEMPT_DELAY';
export const DELAY_SUCCESS = 'app/SupportPage/DELAY_SUCCESS';
export const DELAY_ERROR = 'app/SupportPage/DELAY_SUCCESS';
action.js
import { ATTEMPT_DELAY, DELAY_SUCCESS, DELAY_ERROR } from './constants';
export function attempDelay() {
console.log('attempt delay action called');
return {
type: ATTEMPT_DELAY,
};
}
export function delaySuccess(value) {
console.log('delay success action called');
return {
type: DELAY_SUCCESS,
value,
};
}
export function delayError() {
return {
type: DELAY_ERROR,
};
}
saga.js
import { takeLatest, put } from 'redux-saga/effects';
import { ATTEMPT_DELAY } from './constants';
import { delaySuccess, delayError } from './actions';
export function* delayListener() {
yield takeLatest(ATTEMPT_DELAY, delay);
}
export function* delay() {
console.log('delay saga called')
const value = 10;
try {
yield put(delaySuccess(value));
} catch (e) {
yield put(delayError);
}
}
reducer.js
import produce from 'immer';
import { ATTEMPT_DELAY, DELAY_SUCCESS, DELAY_ERROR } from './constants';
export const initialState = {
value: 5,
isLoading: false,
};
const supportPageReducer = (state = initialState, action) =>
// eslint-disable-next-line no-unused-vars
produce(state, draft => {
// eslint-disable-next-line default-case
switch (action.type) {
case ATTEMPT_DELAY:
draft.isLoading = true;
break;
case DELAY_SUCCESS:
draft.value = action.value || console.log('setting value');
break;
case DELAY_ERROR:
draft.isLoading = false;
break;
default:
break;
}
});
export default supportPageReducer;
index.js
import React, { memo, useEffect } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Helmet } from 'react-helmet';
import { FormattedMessage } from 'react-intl';
import { createStructuredSelector } from 'reselect';
import { compose } from 'redux';
import { useInjectSaga } from 'utils/injectSaga';
import { useInjectReducer } from 'utils/injectReducer';
import makeSelectSupportPage from './selectors';
import reducer from './reducer';
import { delayListener } from './saga';
import { attempDelay } from './actions';
import messages from './messages';
export function SupportPage({ supportPage: { isLoading, value }, delay }) {
useInjectReducer({ key: 'supportPage', reducer });
useInjectSaga({ key: 'supportPage', saga: delayListener });
useEffect(() => {
setTimeout(() => {
console.log('delay called');
delay();
}, 5000);
});
return (
<div>
<Helmet>
<title>SupportPage</title>
<meta name="description" content="Description of SupportPage" />
</Helmet>
<FormattedMessage {...messages.header} />
<h1>{isLoading ? 'loading' : 'not loading'}</h1>
<h1>{value}</h1>
</div>
);
}
SupportPage.propTypes = {
supportPage: PropTypes.object,
delay: PropTypes.func,
};
const mapStateToProps = createStructuredSelector({
supportPage: makeSelectSupportPage(),
});
function mapDispatchToProps(dispatch) {
return {
delay: dispatch(attempDelay()),
};
}
const withConnect = connect(
mapStateToProps,
mapDispatchToProps,
);
export default compose(
withConnect,
memo,
)(SupportPage);
当我在浏览器中打开控制台时,我在从 useEffect 调用 delay() 之前看到了日志,并且出现错误“Uncaught ReferenceError: delay is not defined at eval” 我试着用谷歌搜索这个错误,但没有得到任何与 redux-saga 相关的信息。 在 运行 项目之后,当我进行更改并点击保存时,我注意到了一些事情,它重建了项目,然后 saga 被调用并且所有日志消息都在那里并且值按预期更改。 不知道怎么回事!!!
我发现了我的错误。
function mapDispatchToProps(dispatch) {
return {
delay: dispatch(attempDelay()),
};
}
这里我调用 dispatch 并将 dispatch 的 return 值映射到 delay 对象。它应该是一个函数。
更正为:
delay: () => dispatch(attempDelay()),