cbu*_*ler 2 reactjs redux redux-saga
我在一个带有 redux 的新 create-react-app react 项目中使用 redux-saga,出于某种原因,redux-saga 似乎没有接受调度的操作。减速器中的控制台日志语句显示操作确实到达减速器。关于这一切的奇怪之处在于,我将这个项目基于我成功使用 redux-saga 的其他项目(但不是 create-react-app 的)。我想知道这是版本问题还是需要一些我缺少的支持包。下面是一个完整的代码片段。
从我的 package.json 文件:
"dependencies": {
"axios": "^0.19.0",
"connect-history-api-fallback": "^1.6.0",
"connected-react-router": "^6.5.2",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-google-login": "^5.0.5",
"react-redux": "^7.1.1",
"react-router-dom": "^5.0.1",
"react-scripts": "3.1.1",
"redux": "^4.0.4",
"redux-actions": "^2.6.5",
"redux-immutable-state-invariant": "^2.1.0",
"redux-persist": "^5.10.0",
"redux-saga": "^1.0.5",
"shortid": "^2.2.14",
"styled-components": "^4.3.2",
"styled-modern-normalize": "^0.2.0"
},
"devDependencies": {
"react-hot-loader": "^4.12.11",
"history": "^4.9.0"
},
Run Code Online (Sandbox Code Playgroud)
最外面的 index.js 文件(我的应用程序的入口点):
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './components/App';
import store from './store/config';
const render = (Component) => {
ReactDOM.render(
<Provider store={store}>
<Component />
</Provider>,
document.querySelector('#root')
);
};
render(App);
Run Code Online (Sandbox Code Playgroud)
app.js 文件基本上是一个容器组件,带有来自 connected-react-router 的连接路由器,它具有应用程序标头,然后是带有应用程序路由的开关。我没有展示它,因为它实际上是一些嵌套的组件,它可能只是混淆。
我像这样创建我的商店:
import {
applyMiddleware,
compose,
createStore,
} from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from '../root/rootReducer';
import sagas from '../root/rootSaga';
const sagaMiddleware = createSagaMiddleware();
const initialState = undefined;
const store = createStore(
rootReducer(history),
initialState,
applyMiddleware(sagaMiddleware),
);
sagaMiddleware.run(sagas);
export default store;
Run Code Online (Sandbox Code Playgroud)
接下来是根减速器:
import { combineReducers } from 'redux';
import { connectRouter } from 'connected-react-router';
import authReducer from '../auth/authReducer';
import { stateKeys } from '../../types';
export default history => combineReducers({
[stateKeys.ROUTER]: connectRouter(history),
[stateKeys.AUTH]: authReducer,
});
Run Code Online (Sandbox Code Playgroud)
和根传奇:
import {
watchRegister,
watchSignin,
watchSignout,
} from '../auth/authSaga';
const root = function* rootSaga() {
yield [
watchRegister(),
watchSignin(),
watchSignout(),
];
};
export default root;
Run Code Online (Sandbox Code Playgroud)
我的身份验证传奇:
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects';
import api from '../../services/api';
import * as actions from '../root/rootActions';
function* signInSaga({ payload }) {
try {
console.log('saga hit...');
// console.log('email: ', email);
// console.log('password: ', password);
// yield put(actions.signinRequested());
// const response = yield call(api.signin, { email, password });
// console.log('response: ', response);
// yield put(actions.signinSucceeded(response));
} catch (error) {
console.log('saga failed...');
yield put(actions.signinFailed());
}
}
export function* watchSignin() {
yield takeEvery(actions.signin.toString(), signInSaga);
}
Run Code Online (Sandbox Code Playgroud)
身份验证操作:
import { createAction } from 'redux-actions';
export const signin = createAction('auth/signin');
export const signinRequested = createAction('auth/signin_requested');
export const signinSucceeded = createAction('auth_signin_succeeded');
export const signinFailed = createAction('auth_signin_failed');
Run Code Online (Sandbox Code Playgroud)
最后是登录组件:
import React, { Component, Fragment} from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Link, Redirect } from 'react-router-dom';
import * as actions from '../../store/root/rootActions';
import * as selectors from '../../store/root/rootSelectors';
class Signin extends Component {
...
onSubmitClick = (event) => {
event.preventDefault();
this.setState({ loading: true });
const { email, password } = this.state;
const user = {
email,
password
};
// dispatching the action
this.props.signin(user);
};
renderSigninForm() {
const { email, password } = this.state;
return (
<form className="ui large form">
<div className="ui stacked segment">
<div className="field">
<div className="ui left icon input">
<i className="user icon"></i>
<input onChange={this.handleChange("email")} type="email" placeholder="john.smith@gmail.com" value={email} />
</div>
</div>
<div className="field">
<div className="ui left icon input">
<i className="lock icon"></i>
<input onChange={this.handleChange("password")} type="password" placeholder="Password" value={password} />
</div>
</div>
<div onClick={this.onSubmitClick} className="ui fluid large primary submit button">Log in</div>
</div>
</form>
);
}
render() {
if (this.state.redirectToReferer) {
return <Redirect to="/" />;
}
return (
<div className="ui middle aligned center aligned grid">
<div className="column">
<h2 className="content">Signin</h2>
{this.renderSigninForm()}
</div>
</div>
);
}
}
const mapStateToProps = state => ({
auth: selectors.getAuth(state),
});
const mapDispatchToProps = dispatch => ({
signin: user => dispatch(actions.signin(user)),
});
export default connect(mapStateToProps, mapDispatchToProps)(Signin);
Run Code Online (Sandbox Code Playgroud)
我为这篇文章的史诗般的篇幅道歉,但很难在没有所有内容的情况下提供完整的代码片段。欢迎任何建议:) 提前致谢
小智 5
似乎您的根 saga文件没有调用 saga 方法来启动您的 saga。正如文档所说:您应该调用all()方法来运行您的传奇设置。(例如https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html)。
所以你重构的 rootSaga.js 看起来像这样:
import { all } from 'redux-saga/effects'
import {
watchRegister,
watchSignin,
watchSignout,
} from '../auth/authSaga';
const root = function* rootSaga() {
yield all([
watchRegister(),
watchSignin(),
watchSignout(),
]);
};
export default root;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2641 次 |
| 最近记录: |