react技术栈实践(从前到后撸一个电影搜集应用)
之前做了个好电影搜集的小应用,前端采用react,后端采用express+mongodb,最近又将组件间的状态管理改成了redux,并加入了redux-saga来管理异步操作,记录一些总结 在线地址 手机模式源码 主要功能
一些总结前端前端使用了react,redux加redux-saga,对redux简单总结一下,同时记录一个前后接口调用有依赖关系的问题
一句话总结redux,我觉的就是将组件之间的纵向的props传递和父子组件间的state爱恨纠缠给打平了,将一种纵向关系转变成 redux的核心概念,action,reducer,和store
redux强制规范了我们对状态的操作,只能在action和reducer这些东西中,这样,原本错综复杂的业务逻辑处理就换了个地,限制在了action和reducer中,组件看上去就很干净了。其实,该复杂的东西在哪放都复杂,只不过现在更清晰一点 使用redux不好的地方就是太繁琐了,定义各种action,connect各种组件。。。。。现在又出来一个Mobx,不明觉厉,反正大家都说好~
redux-saga用来处理异步调用啥的,借助于generator,让异步代码看起来更简洁,常用的有 描述一下:
function* checkLogin() { const res = yield Util.fetch('/api/user/checkLogin') yield put(recieveCheckLogin(!res.code)) if (!res.code) { //已登录 yield put(fetchUinfo()) } } export function* watchCheckLogin() { yield takeLatest(CHECK_LOAGIN,checkLogin) }
function* getItemMovie(id) { return yield Util.fetch(`/api/movies/${id}`) } function* getMovieAttach(id) { return yield Util.fetch(`/api/movies/${id}/attach`) } function* getMovieInfo(action) { const { movieId } = action let { login } = yield select(state => state.loginStatus) const res = yield call(getItemMovie,movieId) yield put(recieveItemMovieInfo(res.data[0])) if (res.data[0].attachId && login) { const attach = yield call(getMovieAttach,movieId) yield put(recieveMovieAttach(attach.data[0])) } } export function* watchLoadItemMovie() { yield takeLatest(LOAD_ITEM_MOVIE,getMovieInfo) }
function* getMovieInfo(action) { const { movieId } = action let { login } = yield select(state => state.loginStatus) const res = yield call(getItemMovie,movieId) yield put(recieveItemMovieInfo(res.data[0])) // if (!login) { // //刷新页面的时候,如果此时checklogin接口还没返回数据或还没发出,应触发一个checklogin // //checklogin返回后才能得到login状态 // yield put({ // type: CHECK_LOAGIN // }) // const ret = yield take(RECIEVE_CHECK_LOAGIN) // login = ret.loginStatus // } if (res.data[0].attachId && login) { const attach = yield call(getMovieAttach,movieId) yield put(recieveMovieAttach(attach.data[0])) } }
//将获取附件的动作从 getMovieInfo这个generator中分离出来 function* getMovieInfo(action) { const { movieId } = action const res = yield call(getItemMovie,movieId) yield put(recieveItemMovieInfo(res.data[0])) } function* watchLoadItemMovie() { yield takeLatest(LOAD_ITEM_MOVIE,getMovieInfo) } function* watchLoadAttach() { while (true) { const { movieId } = yield take(LOAD_MOVIE_ATTACH) const { attachId } = yield select(state => state.detail.movieInfo) const attach = yield call(getMovieAttach,movieId) yield put(recieveMovieAttach(attach.data[0])) } } //组件中 componentWillUpdate(nextProps) { if (nextProps.loginStatus && (nextProps.movieInfo!==this.props.movieInfo)) { //是登录状态,并且movieInfo已经返回时 const { id } = this.props.match.params this.props.loadMovieAttach(id) } }
后端后端采用express和mongodb,也用到了redis,主要技术点有
基于token的认证流程
这里采用jsonwebtoken来生成token, jwt.sign(payload,secretOrPrivateKey,[options,callback]) 使用express-jwt验证token(验证成功会把token信息放在request.user中) express_jwt({ secret: SECRET,getToken: (req)=> { if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') { return req.headers.authorization.split(' ')[1]; } else if (req.query && req.query.token) { return req.query.token; } return null; } } 为什么使用redis **采用jsonwebtoken生成token时可以指定token的有效期,并且jsonwebtoken的verify方法也提供了选项来更新token的有效期, 思路:
具体代码
测试覆盖了所有接口,在开发中,因为没什么进度要求就慢慢写了,写完一个接口就去写一个测试,测试写也还算详细,等测试通过了再前端调接口,整个过程还是挺有意思的 mocha 是一个node单元测试框架,类似于前端的jasmine,语法也相近 supertest 用来测试node接口的库 should nodejs断言库,可读性很高 测试的一个例子,篇幅太长,就不放在这了 最后喜欢可以关注下,万一有福利呢。。。。。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |