react + koa2实现的论坛

技术栈

线上地址:点击查看 (访问会有点慢,至于原因,下面会说明)
前端(主要):reactv15.6.1、react routerv4.2.0、reduxv3.7.2、antdv2.13.0、axiosv0.16.2和处理样式的sass;
后端(主要):nodev8.3.0、koa2v2.3.0、koa-routerv7.2.1
数据库:mongodb;
后端是部署在heroku,线上数据库用的mLab,具体的流程不细说,总体来说不是很麻烦。至于为什么选择这两个,因为这两个都可以免费使用...mLab有500m的免费使用空间,但访问及其缓慢及其缓慢及其缓慢,你可以继续来感受下什么是绝望,所以我的建议是你可以clone下来在本地跑。数据库的连接是mongodb默认的端口,你可以在db文件下更改相应的配置。

整体的schema设计参考了cnode社区的,中间碰到的一些问题也是通过看nodeclub的源码去解决的。

页面预览

页面主要分为话题列表页、消息页面、个人信息页面、创建话题页面、个人设置页面、注册页面、登陆页面、404页面。

  • 导航+首页
  • 消息页面
  • 用户信息页面
  • 创建话题页面
  • 用户设置页面
  • 以及稍微复杂的详情页面
  • 404页面
  • 登陆页面
  • 注册页面

文件目录

前端

使用create-react-app脚手架搭建,actions这些都是自己手动添加:

后端

呃,说实话后端我不怎么熟悉,啊呸,是基本不会,自己写了简单的model+controller+middleware这种,也没看到什么好的脚手架,写了大量重复的代码...


大概就是下面这样:

前端的数据结构

前端用了redux,整个state结构如下图:

需要注意的是,react router v4和以前的差别很大,路由参数这些需要通过类似于下面这样手动绑定:

export default withRouter(connect(mapStateToProps,mapDispatchToProps)(NavBar));

react router v4取消indexRoute,取而代之的是exact这个属性。
还有权限方面的,比如登陆后不可以再进入登陆页面,未登陆也不可以进入创建主题页面。
整体的路由设计:

const AppRouter = () => (
  <Router>
    <div>
      <Switch>
        <Route path="/" exact component={Home}/>
        <Route path="/page/:pageNum?" exact component={Home}/>
        <Route path="/category/:categorySlug/:pageNum?" exact component={Home}/>
        <Route path="/topics/:id" component={TopicDetail}/>
        <Route path="/user-info/:loginname" component={UserInfo}/>
        <AuthRoute path='/message' component={Message}/>
        <PrivateRoute path="/login" component={Login}/>
        <PrivateRoute path="/register" component={Register}/>
        <AuthRoute path='/create-topic' component={CreateTopic}/>
        <AuthRoute path='/edit-topic/:topicId' component={CreateTopic}/>
        <AuthRoute path='/setting' component={Setting}></AuthRoute>
        <Route component={NoMatch}/>
      </Switch>
    </div>
  </Router>
);

值得一提的是v4版本关于?a=1&&b=2这种不再提供默认的解析支持,好像是因为觉得这种写法不规范,解析的话需要依赖第三方的query-string这个包。我没有用,不做分析。我第一次使用v4,中间还是碰到许多坑,不过基本上都能在在网上找到相应的介绍和解决方法,推介使用谷歌搜索,关于官方文档,有中文的版本文档

期间react出了新版本v 16.0.0,我升级了一下,但antd并不能无缝切入到v16,其中部分组件使用直接报错,所以使用antd的话,不建议升级到最新版本,也有人提了issues点击查看
还有关于antd同一个容器多个form的情况,我在设置这个页面有做处理,我是把表单拆分开的。

后端的设计

hhh,请原谅我笑出身,对后端的理解基本上只是皮毛,看过一段时间nodekoa,所以我就不做详细分析了,怕误导新人,网上有大量高质量的文档和实例,我就安安静静当条咸鱼,把自己在开发中遇到的问题说明一下。

1.关于async和await,期间碰到一个问题,我需要根据评论还是啥数组id取出每个id对应的评论,我一开始是这样写的:

const xxx = idList.map(id => {
  const result = await findReplyById(id);
  //xxx
  return result;
})

我勒个去,直接报错,然后我看了下,额,await只能在async下面使用,不能在function下,后面修改成Promise.all()的形式。

2.token的处理,用的是node-jsonwebtoken,看了狼叔的博客RESTFul,介绍的比较详细,将整个流程梳理了一遍。我再大概说一下整体流程吧,用户登陆,后端通过对账户和密码的验证后,返回给前端一个token,前端拿到这个token,保存到本地,后面发请求时,通过axios拦截器在所有的请求头里加上这个token,后端通过解析能拿到登陆用户的id。如果token超时,后端返回个错误码给前端,前端通过拦截器对返回的错误做判断,如果是超时,则跳转到登陆页面。代码如下:

//如果有token就在请求头里面带上
axios.interceptors.request.use(function (config) {
  const token = localStorage.getItem('login_token');
  if (token) {
    config.headers['x-access-token'] = token;
  }
  return config;
},function (error) {
  return Promise.reject(error);
});

//对登陆过期做处理
axios.interceptors.response.use(function (response) {
  return response;
},function (error) {
  const { errCode } = error.response.data;
  if (errCode && errCode === 100) {
    localStorage.removeItem('login_token');
    history.push('/login');
  }
  return Promise.reject(error);
});

3.lodash是个好东西。

4.呃,貌似也没其他什么要说明的,大部分都是数据库的增删查改...后面想到什么再补充吧。

总结与源码

源码放在了github
没有使用immutable.js,但推介使用,不然性能不好。
最新的react v16prop-types从react中移了出来,个人感觉react是希望使用Facebook自家的flow去替代。制作略粗糙,仅供参考。内容就这么多,一些小的细节可能没有提到,自己会继续补充内容。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom