使用 Redux 和 Sagas 的 React 身份验证应用程序
由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!
概述
我将在本文中探讨以下内容:
在开发身份验证应用的过程中,我们会探讨以上几点。
首先要明确一点:Redux 与 React 无关。Redux 也可以用于 Angular。尽管如此,Redux 与 React 的兼容性依然非常出色。那么,Redux 究竟是什么呢?
简单来说,Redux 是一个“用于管理应用程序状态的开源 JavaScript 库”。它可以帮助你编写行为一致的应用程序。
为了增加趣味性,我们来使用真正的 API。你可以使用我仓库中提供的后端 API 服务,例如使用 Node 进行身份验证,并按照 README 文件中的说明运行该服务;或者你也可以使用你自己的基于 JSON Web Token 的 API。
演出开始!

要开始演示,我们需要先部署我们的 React 应用。请按照以下命令操作。
请确保您已create-react-app安装
a)$ npm install -g create-react-app
创建 React 应用
b)$ npx create-react-app my-app
c)进入 my-app 目录$ cd my-app
运行 React 应用
d)$ npm start
让我们安装所有必需的软件包
e)$ npm i redux react-redux redux-saga react-router redux-form --save
现在你的 React 应用已经部署完毕。那么,让我们开始吧。
目录code结构如下:
src/
login/
actions.js
constants.js
sagas.js
selector.js
reducer.js
index.js
components/
login.js
register/
actions.js
constants.js
sagas.js
selector.js
reducer.js
index.js
components/
register.js
user/
reducer.js
actions.js
constants.js
share/
Messages.js
helpers/
api-errors.js
check-auth.js
Main.js
index-reducer.js
index-sagas.js
让我们浏览一下我们刚刚创建的文件夹和文件:login/,register/&&user/login/是register/我们将要使用的路由。
现在来看我们创建的文件:
a)actions.js是用于将数据从应用程序发送到 store 的信息有效负载。它们是纯 JavaScript 对象
。b)reducer.js指定应用程序状态如何响应发送到 store 的数据而改变。c
)constants.js存放 action 和 reducer 的常量
。d)sagas.js管理非纯操作,例如异步操作(如数据获取) 。e
)是所有 reducer 和 saga 的集合中心。index-reducer.jsindex-sagas.js
我们来看代码。
1)在目录中src/index
- 完整的代码
index.js如下:
import React from 'react';
import ReactDOM from 'react-dom';
import { applyMiddleware, createStore, compose } from 'redux';
import { Provider } from 'react-redux';
import createSagaMiddleware from 'redux-saga';
import { routerMiddleware } from 'react-router-redux';
import { history } from './history';
import { Router } from 'react-router-dom';
// Import all of our components
import App from './App';
import './index.css';
// Import the index reducer and sagas
import IndexReducer from './index-reducer';
import IndexSagas from './index-sagas';
import registerServiceWorker from './registerServiceWorker';
// Setup the middleware to watch between the Reducers and the Actions
const sagaMiddleware = createSagaMiddleware();
const routersMiddleware = routerMiddleware(history);
/*eslint-disable */
const composeSetup =
process.env.NODE_ENV !== 'production' && typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
: compose;
/*eslint-enable */
const store = createStore(
IndexReducer,
composeSetup(applyMiddleware(sagaMiddleware, routersMiddleware)) // allows redux devtools to watch sagas
);
// Begin our Index Saga
sagaMiddleware.run(IndexSagas);
ReactDOM.render(
<Provider store={store}>
<Router history={history}>
<App />
</Router>
</Provider>
document.getElementById('root')
);
registerServiceWorker();
- 现在我们来仔细看看上面的锅炉规范。
import React from 'react';
import ReactDOM from 'react-dom';
import { applyMiddleware, createStore, compose } from 'redux';
import { Provider } from 'react-redux';
import createSagaMiddleware from 'redux-saga';
import { routerMiddleware } from 'react-router-redux';
import { history } from './history';
import { Router } from 'react-router-dom';
// Import all of our components
import App from './App';
import './index.css';
// Import the index reducer and sagas
import IndexReducer from './index-reducer';
import IndexSagas from './index-sagas';
import the required pakages
-
中间件
const sagaMiddleware = createSagaMiddleware() const routersMiddleware = routerMiddleware(history);
创建 Redux 中间件并将 Saga 连接到 Redux Store
-
创建店铺
/*eslint-disable */ const composeSetup = process.env.NODE_ENV !== 'production' && typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose /*eslint-enable */
const store = createStore(
IndexReducer,
composeSetup(applyMiddleware(sagaMiddleware, routersMiddleware)),
)
Here ` composeSetup(applyMiddleware(sagaMiddleware, routersMiddleware)),` allows redux to watch sagas and router
+ To Start the Saga middleware
```javascript
sagaMiddleware.run(IndexSagas)
只能在该applyMiddleware阶段之后运行。
- 现在让我们渲染 Index.js 文件。
ReactDOM.render(
<Provider store={store}>
<Router history={history}>
<App />
</Router>
</Provider>,
document.getElementById('root')
);
registerServiceWorker();
所以,我们在这里提供一个带有 store 的 React 应用,获取它提供的 store。<Provider store={store}>
2)现在让我们进入正题index-reducer.js
```javascript
import { combineReducers } from 'redux'
import { reducer as form } from 'redux-form'
const IndexReducer = combineReducers({
form
})
export default IndexReducer
```
该combineReducers辅助函数将一个包含多个归约函数的对象转换为一个可以传递给它的单个归约函数。createStore
3)让我们进入正题index-saga.js
import { all } from 'redux-saga/effects';
export default function* IndexSaga() {
yield all([ ]);
}
4) 现在我们已经完成了 reducer、saga 和主索引的索引,接下来让我们进入App.js:
import React, { Component } from 'react';
import './App.css';
import Main from './Main';
class App extends Component {
render() {
return (
<div className="App">
<Main />
</div>
);
}
}
export default App;
<Main />我们的路线就位于应用程序中。
5) 我们分离出一个组件来处理应用程序的路由,即主组件。
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import Login from '../src/login';
import Register from '../src/register';
export default class Main extends React.Component {
render() {
return (
<main>
<Switch>
<Route path="/login" component={Login} />
<Route path="/register" component={Register} />
</Switch>
</main>
);
}
}
让我们深入探讨一下,Switch <Switch>它的独特之处在于它只渲染一条路线。相比之下,所有<Route>匹配位置的路线都会被渲染。