{"id":13634596,"url":"https://github.com/lumia2046/cnode","last_synced_at":"2025-04-18T23:32:22.169Z","repository":{"id":14680037,"uuid":"76414104","full_name":"lumia2046/cnode","owner":"lumia2046","description":"基于react编写的cnodejs论坛第三方webapp","archived":false,"fork":false,"pushed_at":"2023-03-01T16:14:01.000Z","size":8973,"stargazers_count":140,"open_issues_count":16,"forks_count":41,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-11-09T04:35:44.595Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://lumia2046.github.io/cnode/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lumia2046.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-12-14T01:43:22.000Z","updated_at":"2024-10-16T17:17:42.000Z","dependencies_parsed_at":"2024-01-17T15:04:49.161Z","dependency_job_id":"4ca32b54-57a0-4add-b4b9-05416ed1e544","html_url":"https://github.com/lumia2046/cnode","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumia2046%2Fcnode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumia2046%2Fcnode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumia2046%2Fcnode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumia2046%2Fcnode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lumia2046","download_url":"https://codeload.github.com/lumia2046/cnode/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249565246,"owners_count":21292427,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T00:00:26.961Z","updated_at":"2025-04-18T23:32:21.866Z","avatar_url":"https://github.com/lumia2046.png","language":"JavaScript","readme":"## 项目简介\n一个WebApp版的cnode客户端，项目采用react技术栈构建。组件选用的是[Material-UI](http://www.material-ui.com/)，让界面更适合触控操作。\n- 感谢来自[cnodejs论坛](https://cnodejs.org/)官方提供的api！\n\n## 功能\n- 首页列表，下拉时自动加载下一页，在顶端上拉刷新\n- 主题详情，登陆后能够收藏，评论和点赞\n- 消息提醒，能查看消息详情和清空所有未读消息\n- 个人主页，包括最近参与，回复，以及收藏的主题\n- 发表主题，成功后能跳转到相应主题页面\n- 页面后退，能还原数据和滚动位置\n\n## 运用的技术主要有:\n- 采用react技术栈，通过Redux来管理页面状态，通过Router来设置页面路由\n- 组件选用的是Material-UI，不再自己造轮子，既美观又能方便触控操作\n- 使用react-route v4 和 react原生的react-transition-group v2 来实现路由切换动画\n- 使用react-flip-move插件来实现list的加载动画\n- 应用`isomorphic-fetch`库代替`XMLHttpRequest`实现网络请求\n- 使用`PostCSS`对CSS进行预处理\n- 通过`CSSModules`处理模块内部的类名\n\n## 预览\n[DEMO](https://lumia2046.github.io/cnode/)\n\n## 运行项目\n```\n  git clone https://github.com/lumia2046/cnode.git\n  cd cnode\n  npm install\n  npm start\n  打开浏览器访问：http://localhost:5678\n```\n\n## 生产项目\n```\n  windows下\n  npm run build-win\n  linux、mac下\n  npm run build-win\n```\n\u003c!-- \n## 状态树\n本项目使用redux管理状态,状态树如图:\n![截图](https://github.com/lumia2046/cnode/blob/master/stateTree/stateTree.png)  \n基本思路是每个页面对应一个reducer,管理本页面的状态。其中:\n- `homePage`对应主页信息，还包括了浏览的主题类别等状态\n- `article`对应文章内容页面，能缓存多篇，所以状态信息中提供了当前正在阅读的主题信息\n- `login`对应登陆账号的信息页面，包括是否登录成功等状态\n- `profile`代表用户的信息页面，比如用户名，积分情况等，还包括发表、回复和收藏的主题\n- `publishTopic`对应发表主题页面，包括主题是否发送成功等状态\n- `message`对应登陆账号的消息界面，还包括了未读消息是否被标记已读等状态\n\n## 总结\n\n- 对react组件及其生命周期有了更深入的了解\n  - 如果需要在组件更新的生命周期里setState()，应该在componentWillReceiveProps(或者componentWillUpdate)里通过对this.props和newProps里面的属性做出准确判断后再去setState()，否则会导致组件更新死循环以致页面卡死\n  - 在组件的生命周期里调用dispatch发送不带异步的action时，每发送一个action都会更新一次store。但是在事件回调的方法里多次调用dispatch发送不带异步的action时，只会在最后一个action发送完毕才更新一次store，想要每次action都更新store，那么必须手动将其封装为异步操作\n  - 公共组件最好不要设置自己的状态，应该由父组件管理其状态\n\n- 对es6有了更深入的了解\n  - 当采用es5写法时，React 自动将组件绑定给所有的事件回调方法中的this，这种自动绑定的行为只适用于当组件是用 React.createClass 创建时。如果用 ES6 的类来定义组件，那么事件方法中 this 的值就是 undefined，除非你自己显式绑定它\n  - 为了省略es6中事件方法的绑定，可以将事件方法写成箭头函数的形式，这种写法在react文档中标注为es7+，eg: 把handleClick(){}写成handleClick = () =\u003e {}即可,但是react生命周期函数不支es7+这种写法\n  - 利用扩展运算符和对象的解构赋值极大的简化了react组件间props的传递的书写。\n  eg: \u003c Reply  {...({login,dispatch,profile})} / \u003e只需这样，就可以把login,dispatch,profile三个变量当作props传递给Reply组件，需要注意的是解构对象本身时必须用括号括起来，否则解析器会把{}里的内容理解成一个代码块，而不是赋值语句\n\n- 对React技术栈有了深入的了解\n  - react-router的history属性，当设置为browerHistory时，需要对服务器改造。否则用户直接向服务器请求某个子路由，会显示网页找不到的404错误。\n  - redux通过connect连接react组件，只有mapStateToProps里return的对象的属性发生改变，组件才会去更新。store中有的但是return的对象里不存在的属性改变时，组件不会去更新，因为这样没有意义\n\n- 使用了模块化编程后，页面整体逻辑变得清晰很多，每个模块里的css和js都只负责管理一个对应的组件。尤其是用了css这一块，用css-loader开启CSS-Modules后，就再也不用为类名的语义化和重复去烦恼 --\u003e\n","funding_links":[],"categories":["JavaScript","Awesome-CNode"],"sub_categories":["React"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flumia2046%2Fcnode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flumia2046%2Fcnode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flumia2046%2Fcnode/lists"}