上回说到用react写了一个带header的首页,我们这次实践就使用redux进行状态管理
rudex应用中所有的 state 都以一个对象树的形式储存在一个单一的 store 中。
惟一改变 state 的办法是触发 action,一个描述发生什么的对象。
为了描述 action 如何改变 state 树,你需要编写 reducers。
我们接下来开始开始进行登陆与注册的状态管理
首先在 src 目录下创建 redux 文件夹,目录如下
digag
├── readme.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ └── favicon.ico
│ └── index.html
│ └── manifest.json
└── src
└── components
└── index
└── header.js
└── logindialog.js
└── registerdialog.js
└── containers
└── app
└── app.js
└── app.css
└── redux
└── action
└── users.js
└── reducer
└── auth.js
└── users.js
└── sagas
└── api.js
└── sagas.js
└── selectors.js.js
└── users.js
└── store
└── store.js
└── app.test.js
└── index.css
└── index.js
└── logo.svg
└── registerserviceworker.js
代码可从此获取
记得在 package.json 中更新依赖
接下来我会开始解释关键代码action
action/users.js
/*
* action 类型
*/
export const register_user = 'register_user';
// 省略其他action 类型
/*
* action 创建函数
*/
export const registeraction = (newuser) => {
return{
type:register_user,
data: newuser,
}
};
// 省略其他 action 创建函数
reducer
reducer/users.js
//immutable data 就是一旦创建,就不能再被更改的数据。
//对 immutable 对象的任何修改或添加删除操作都会返回一个新的 immutable 对象。
import immutable from 'immutable';
//从 action 导入需要的 action 类型
import {register_user, register_user_success, register_user_failure} from '../action/users';
// 初始化状态
const initialstate = immutable.fromjs({
newuser: null,
error: null,
savesuccess: false,
});
// reducer 就是一个纯函数,接收旧的 state 和 action,返回新的 state。
export const users = (state = initialstate, action = {}) => {
switch (action.type) { // 判断 action 类型
case register_user:
return state.merge({ // 更新状态
'newuser': action.data,
'savesuccess': false,
'error': null,
});
case register_user_success:
return state.set('savesuccess', action.data);
case register_user_failure:
return state.set('error', action.data);
default:
return state
}
};
store
store/store.js
import {createstore, combinereducers, applymiddleware } from 'redux';
import createsagamiddleware from 'redux-saga'
import * as reducer from '../reducer/users';
import rootsaga from '../sagas/sagas';
const sagamiddleware = createsagamiddleware();
const store = createstore(
combinereducers(reducer),
applymiddleware(sagamiddleware)
);
sagamiddleware.run(rootsaga);
export default store;
然后在入口文件使用 storesrc/index.js
import {provider} from 'react-redux';
import store from './redux/store/store';
// 省略其他
reactdom.render(
<provider store={store}>
<app />
</provider>, document.getelementbyid('root')
);
在 app.js 中获取 action 和 状态import {registeraction, loginaction} from '../../redux/action/users';
import {connect} from react-redux;
import {bindactioncreators} from redux;
//省略其他
class app extends component {
render(){
return(
<div classname="app">
//省略
</div>
)
}
}
export default connect(
(state) => {
// 获取状态 state.users 是指 reducer/users.js 文件中导出的 users
// 可以 `console.log(state);` 查看状态树
return { users: state.users }
},
(dispatch) => {
return {
// 创建action
registeractions: bindactioncreators(registeraction, dispatch),
loginactions: bindactioncreators(loginaction, dispatch),
}
})(app);
// 在app 组件的props里就有 this.props.users this.props.registeractions this.props.loginactions 了
// 需要注意的是这里this.props.users是immutable 对象,取值需要用this.props.users.get('newuser')
// 也可在 reducer 里改用 js 普通对象
装饰器版本:
需要在babel中开启装饰器
装饰器插件babel-plugin-transform-decorators-legacy
@connect(
(state) => {
console.log(state);
return ({
users: state.users,
});
},
{registeractions: registeraction, loginactions: loginaction}
)
最后把 registeractions 传给registerdialog子组件,src/components/index/registerdialog.js
// 省略其他代码
handlesubmit = (e) => {
e.preventdefault();
// 验证表单数据
this.refs.user.validate((valid) => {
if (valid) {
// this.state.user 为表单收集的 用户注册数据
this.props.registeractions(this.state.user);
this.setstate({loading: true});
}
});
};
流程是:调用 action
this.props.registeractions(this.state.user);
返回action 为
{
type:register_user,
data: this.state.user,
}
reducer 根据action类型更新状态
switch (action.type) {
case register_user:
return state.merge({
'newuser': action.data,
'savesuccess': false,
'error': null,
});
//省略其他代码
这时我们的store里的状态 newuser就被更新为 注册弹窗里收集的数据
到这里都还是同步的action,而注册是一个异步的操作。
以上就是分享一个react的实践项目的详细内容。