博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
react案例->新闻移动客户端--(react+redux+es6+webpack+es6的spa应用)
阅读量:6242 次
发布时间:2019-06-22

本文共 6473 字,大约阅读时间需要 21 分钟。

今天分享一个react应用,应在第中说要做一个react+redux+xxx的应用。已经做完一部分,拿出来分享。github地址为:~

这里实现了一个新闻移动站的spa。本来想写pc端的,但是比较懒,而且因为主要是react的项目,关于css和布局的细节就是糊弄人的了。T.T,这里只说关于这个项目的js部分。

这里的功能很简单,有一下几点:

1,按”心“排序

当比上一个多了,就会排到前面。

2.评论部分

新闻的评论部分类似qq空间的评论

当然,也可以点击新闻回复的哦。

=============================================

大家看到了,功能比较简单,大家clone 项目下来,直接能用的,里面已经传了我用webpack打包好的文件。

=============================================

bundle.js有3m+,这个完全是因为我加了很多库进去,比如轮播图的swiper等等,而且这些东西都是没有压缩过的。你压缩完之后,会觉得react做移动端也可以的。

就不要再问我为什么不用rn做这个。。因为我不会T.T

=============================================

要看懂本文也需要一定的基础,比如es6基础,react和redux基础。

=============================================

最后一点废话,这个东西还没有做完,只是一部分,接下来会用redux的router把它作为一个完全的spa,并且完善它的测试部分。大家期待吧~

=============================================(主文分界线)

好,接下来介绍我们的主角redux,不会的可以转到我的另一篇博文:

redux,昨天花了一上午,竟然看完了它全部的源码。跟你们说,它未压缩的redux.js仅有600行。angular已经1w+行了。。。

主要的是很简单,源码一看就懂,而且redux完全是fp,也就是函数式编程,它内置了一些函数式编程的例子。运用fp的库还有lodas和underscore。我将会写另一篇介绍fp与redux的博文~~

分析代码之前,先给出文件目录:

这个目录是官方example的目录,我就直接拿来用了。webpack整理的文件在public中,bootstrap没有在webpack中打包,项目中一般也用不到,其他的css和js文件都打包进去了。

其中,fonts是字体,dist存放了webpack打包后的js和css文件,public里面是轮播图js文件和图片文件。test是测试文件,现在还没写。因为不是tdd。。

剩下的actions存放的是redux的action文件。components存放的是react的组件,containers是redux如何封装组件的配置文件。reducers是redux的reducer文件,store是创建store的配置文件。

webpack主入口是index.js 它里面是添加了一些应用需要的文件,比如import Swiper from "./public/js/swiper-3.3.1.min.js"和import "./public/js/swiper.min.css",还有main.css

import React from 'react'import { render } from 'react-dom'import { Provider } from 'react-redux'import App from './containers/App'import configureStore from './store/configureStore'import "./dist/main.css";import Swiper from "./public/js/swiper-3.3.1.min.js"import "./public/js/swiper.min.css"import 'react-bootstrap';const store = configureStore();render(  
, document.getElementById('root'))

 

大家会看到这个项目跟上一个redux入门中的项目结构,甚至代码都类似,因为就是从上一个代码的基础上改的,不明白可以看。

主页就不多说了,开始的页面布局和引入css文件和打包之后的js文件。

主要说一下上面提到的功能。

首先是排序。排序的原理是什么?根据心排序,心的多少。

Box是那三个新闻,这里会根据children来循环遍历出来,那个children是啥呢?是redux的store的counter数据排序之后的数据。

可以看到,我自己写了一个数据排序,根据数据的val属性排序,然后遍历,就是完成了心的特性。

state={  counter:{    one:{id:1,counter:0,title:"xxxx" ,time:1},    two:{id:2,counter:0,title:"xxxx", time:1},    three:{id:3,counter:0,title:"xxxx",time:1}  }  }

 

这里的counter数据,counter是心的数量。排序就不说了,看代码吧。

评论功能呢,有三个难点。1是点击回复弹出input框,2是如何回复当前的评论。比如我回复的评论必须是这个评论,而不是下一个。3就是如何把评论内容显示出来。

最难的就是2了。这个还要设计一下store的数据结构。我用了一个小方法避免了添加id。这个以后再说。

1。点击弹出input框。

写react或者ng应用也不能用jquery的思想写了。点击弹出不能用click事件操作dom了。转变为react的思想,props和state。于是,要这样写。

这是根据state渲染dom阿,然后点击操作state。对了,react有个操作state的方法和初始化state的方法来着。叫getInitialState。

这里有个隐藏的坑,es6的写法不能用getInitialState。于是我就像上面这样写。es6怎么写state呢。于是我在下面的组件里又这样写:

这个state成为了这个组件的一个属性,但是确实没法用getInitialState了。不过可以用  this.setState({display: false})。这样写。来操作state

2,这个比较麻烦,首先看一下我设计的评论的store:

var data=[      [         {            text:"这里是评论1",            huifu:["huifuxxxxxxxxxxxxx",'2xxxxxxxxxxxxxxxxxxxx','3xxxxxxxxxxxxxxxxx']          },         {            text:"这里是评论1.2",            huifu:["huifuxxxxxxxxxxxxx"]          }      ],[          {            text:"这里是评论2",            huifu:["huifuxxxxxxxxxxxxx",'2xxxxxxxxxxxxxxxxxxxx','3xxxxxxxxxxxxxxxxx']          }      ],[          {            text:"这里是评论3",            huifu:["huifuxxxxxxxxxxxxx",'2xxxxxxxxxxxxxxxxxxxx','3xxxxxxxxxxxxxxxxx']          }        ]      ]

 

这是整个评论的部分,包括回复。如果你要添加评论就在data[文章id].push(一样结构的评论数据),回复也是直接添加数据。

问题来了,那我们怎么保证这个回复是这个评论的呢,比如我回复123,你怎么知道是评论1的还是评论1.2(代码中的评论1.2)的呢?

这里有个小方法。我的评论框是独立于遍历之外的,就是说,你不能给他传一个文章id。那怎么办?

它取本组件的state。然后评论操作state。就是这样。评论在打开一个回复input的时候,传入本评论的id,改变本组件的state,然后就不管它的事了。

这里的小方法避免了每个评论都加一个id属性,而是一个评论数组,用的就是数组map方法的keys--

keys,是数组的键,也就是0,1,2,3用这个当作文章id。可以的!

注意这里你循环出子组件的时候,必须给他一个key的props,由于react的diff算法,必须保证子组件的位置和渲染正确,传一个key,那正好,没有id我就用这里的keys传了:

这样就没问题了。

3。显示的问题,就是上面的遍历的问题了,输入框的显示就是组件自身state的问题了。

看组件是如何显示:

{          data[newId].map(function (items,keys) {            return (              
游客: 回复 转发

{items.text}

{ items.huifu.map(function (item,keyss) { return (
游客回复:回复 转发

{item}

) }) }
) }) }

 

data数组是我们的数据,上面给了格式。循环遍历。

主要的是回复框的显示,操作state,这里给了他一个display属性,但是他不是true和false,而是false和keys,这个keys就是当前评论的id,这个id成为遍历的keys属性。

1的时候那张图就是根据display显示,这就不多说了。

react的优势:

其实这么多文件夹,这么多js文件,用js写,逻辑又清楚又快,而用react写还带有学习成本。为啥用react写。抛开赶前端潮流不说。react的优势在于维护起来爽翻天。

js写这些逻辑刚开始写完是很清晰,我觉得过一段时间以后,想维护就很难了吧。还有一点,我想改数据的时候直接修改state,想加一个新闻就复用我的组件,根据react的虚拟dom的算法,也是不慢的。

用redux的优势就是等这个新闻项目做大,一堆一堆的js代码,如果有redux维护那就简单多了。因为纯函数的关系,redux的测试也是非常好写的。redux压缩前600行代码,加上react也是轻量级框架,这点也是很受人好评的。

用这些框架都是类似,都是数据流,他们让你用数据控制页面。ng也是如此,操作仅仅是修改数据,而不会频繁的操作dom。这是框架的优点。react在此基础上做到的低耦合,单项数据流。经常听到有react维护比较爽的呼声。-。-好维护,低耦合,轻量级。正好符合现在前端对框架的要求。于是好多人选择了react。还有JSX的写法也是比较爽的0.0react背后还有facebook撑腰。嗯,必火。。。

关于本新闻端的问题:

问题在于这里:三篇新闻,每一篇当作一个事件来处理,于是--

export const LOVE_COUNTER_ONE = 'LOVE_COUNTER_ONE'export const LOVE_COUNTER_TWO = 'LOVE_COUNTER_TWO'export const LOVE_COUNTER_THREE = 'LOVE_COUNTER_THREE'export const TXST_COUNTER_ONE = 'TXST_COUNTER_ONE'export const TXST_COUNTER_TWO = 'TXST_COUNTER_TWO'export const TXST_COUNTER_THREE = 'TXST_COUNTER_THREE'export const HF_COUNTER_ONE = 'HF_COUNTER_ONE'export const HF_COUNTER_TWO = 'HF_COUNTER_TWO'export const HF_COUNTER_THREE = 'HF_COUNTER_THREE'

 

有人会说,如果100篇新闻,岂不是写n多的action?

当初在写的时候,想的是作为新闻的主页,我只放3个新闻,后面加一个更多,点开打开新闻列表页。当然,如果把这个作为新闻列表页那确实要写n多的xxx。。

那当这个新闻端改为新闻列表页怎么写呢?

首先构建一个store,把新闻id,新闻内容写进去。当然也可以组合它的评论和回复,不组合,通过id关联也是可以的。。(怎么感觉像数据库了0.0)

那这里的action就变了,改为TXST_COUNTER_NEWS,当然,这个action需要传文章的id。这个不麻烦。

reducer这里就根据文章id操作store,如果不组合评论和回复,那么,这个新闻store只需要删减新闻内容。注意新闻删了,对应的评论和回复也要删除。

组合评论和回复呢,那么也是同样,评论和回复的内容留给游客们去添加。

组件里就注意了,因为新闻组合了,那么上面就需要传一个新闻id,智能组件根据id传方法与数据给呆滞组件。。原理是这样。大家可以试着修改一下,自己动手能学到很多东西。

 还有就是webpack打包文件太大怎么办。我这个文件3m,本地加载都要143ms,这段时间3张下载完的图片并排,很丑。。

这里的减少体积大小的方法就是关闭source map,devTool也关了。重复的文件打包成common.js,还有就是压缩文件- -,当然这些都是生成环境下了。

这里测试了一下(未传到github),未压缩前可以弄到864k,当然公共库,比如Swiper可以用cdn,压缩完后这样一个数量级的应用就可以用在移动端了。

这里的操作是-删除没用的react-bootstrap,删除重复的style-loader,删除source-map及webpack hot replace及一些webpack常用插件。

还有一点,把文件作为chunk按需加载,这个貌似这个场景下还是不需要的。

需要注意的就这么多,接下来会添加路由功能,使他真正的成为spa的应用。当然,大神的标志之一---会不会写测试也会一并补齐。敬请期待~

最新更新:2016-04-25    单元测试已经补齐哦~ 博文地址:~    github地址:~

 

转载于:https://www.cnblogs.com/dh-dh/p/5349368.html

你可能感兴趣的文章
9.[Java开发之路](6)File类的使用
查看>>
折半插入排序(binary insertion sort)
查看>>
打包常见问题
查看>>
javascript解析json
查看>>
在Ubuntu下编译WebKit源码
查看>>
amazeui 移动开发
查看>>
python2 与python3中最大的区别(编码问题bytes&str
查看>>
HDU 2243 AC自动机+DP+矩阵
查看>>
什么叫脱字符合^
查看>>
git版本控制管理实践-2
查看>>
HTTP基础知识(三)
查看>>
如何有效释放DB2所占的磁盘空间?
查看>>
三分法
查看>>
第 8 章 容器网络 - 058 - flannel 概述
查看>>
Mongodb删除collection
查看>>
ArcEngine应用程序中无法实现TOC图层多选
查看>>
Java-笔记9-复习
查看>>
python---基本数据结构
查看>>
Windows下JDK,Tomcat,Eclipse安装配置
查看>>
vue的checkbox或多选的select的代码例子
查看>>