基于React,Redux以及wilddog的聊天室简单实现
本文主要是使用ReactJs和Redux来实现一个聊天功能的页面,页面极其简单。使用React时间不长,还是个noob,有不对之处欢迎大家吐槽指正。
还要指出这里没有使用到websocket等技术来实现后端逻辑,而是使用了wilddog充当后端。具体关于wilddog的介绍,戳这里。
目标:我期望的页面长这样,一个简单的消息列表,下面有个输入框和提交按钮,任何人可以在上面说话,并可以看到别人说的话,就这么简单。
1. React和Redux
React这么火,我就不多说了。Redux是一个类flux的应用框架,和flux一样是单向数据流,目前用来主要是对flux进行了一些优化,如将action变为简单的对象,store也是一个简单的对象树,引入了reducer来处理action,reducer本身是pure function,调试起来也极为方便,还可以配合使用hot-loader以及redux-dev-tool实现time travel调试功能,用起来还是有点爽爽的感觉。
2. 开始coding
"不想看扯淡,只要看源码的"戳这里:D。
文件目录是这样的:
项目是使用webpack打包的,也用了dev-server,有兴趣的同学可以自己看webpack目录和server.js。
这里主要关注src下面的内容:
store创建一个唯一的store,存放项目中所有的数据。
reducers: 初始化store的部分内容,在这里是个空对象。还有处理store的函数,这里只有一个init的工作,就是用action中传过来的chats字段替换当前的state,这里的业务逻辑对应的是,每当聊天室有新的消息传过来,都会整个替换当前的聊天内容,这里可能会有疑问为什么要这样,主要是因为wilddog传给我的就是一个完整的列表,后面仔细会介绍wilddog。
const initialState = {};
export function chat(state = initialState, action) {switch (action.type) { case INIT_CHAT: return Object.assign({},state,action.chats); default: return state; }}
action : 只是一个简单的表示操作动作的对象。
export function init(chats){ return { type : INIT_CHAT, chats }}
export function getChats(){
return function(dispatch){ ref = new Wilddog("https://firstblood.wilddogio.com/"); ref.on("value", function(snapshot) { console.log(snapshot.val()); dispatch(init(snapshot.val())); }, function (errorObject) { console.log("The read failed: " + errorObject.code); }); }}
export function postMsg(msg){
return function(dispatch){ var postsRef = ref.child("msgs"); postsRef.push({ date: Date.now(), msg }); }}
很显然,除了init是简单的对象之外,还有两个相对复杂的函数。这里用到redux-thunk,其作用就是把一些比较复杂的动作(例如这里用到的异步操作)封装到一个action中去,redux-thunk是redux的一个middleware,redux的dispatch无法处理对象之外的内容,例如函数,将redux-thunk放进去了就可以了:
import thunkMiddleware from 'redux-thunk';const createStoreWithMiddleware = compose(
applyMiddleware( thunkMiddleware, logger ), window.devToolsExtension ? window.devToolsExtension() : f => f)(createStore);
这里的getChats()首先新建了一个wilddog实例,连接我在wilddog上定义好的项目上,
野狗提供的on()函数可以通过websocket来监听数据是否发生了变化,正如这里写的,每当数据发生变化都会dispatch一次init动作,来将页面的数据重新渲染。
而postMsg则是将新的消息推到wilddog上。这样会出发wilddog的数据变化,然后反过来会触发我们之前定义在on()回调里面的内容,及重新获取数据,渲染页面。
container/chat.js: 页面主体的react组件。首先将这个react组件和redux的store关联起来,这里用到的react-redux中的connect函数,在注解里完成了:
@connect( state => state.chat, dispatch => bindActionCreators(actionCreators, dispatch))
大家是否还记得我们之前定义好了获取页面初始消息列表的getChats函数,在这里被调用:
componentDidMount(){ this.props.getChats(); this.setState({ input : "" }); }让我们来关注页面html的代码,首先是消息列表:
<List className="msgList" ref="msgList"> <Subheader>Chat</Subheader> { _msgList.map((msg,index)=> <section key = {index} ref="msgItem"> <ListItem leftAvatar = {<Avatar src={require('./files/avatar.png')} />} primaryText = {moment(msg.date).format('YYYY-MM-DD HH:mm:ss')} secondaryText={ <p> {msg.msg} </p> } secondaryTextLines={1}/> <Divider inset={true} /> </section> ) } </List>循环_msgList来输出每一条消息,这里用到List,ListItem是material-ui中的。这个_msgList是从store中取出的:
const { msgs } = this.props; let _msgList = []; for(let i in msgs){ _msgList.push(msgs[i]); }接下来是输入框和say按钮部分的代码:
<div className="post">
<form onSubmit={this.handleSubmit.bind(this)}> <TextField ref="input" className="input-sec" underlineStyle={inputStyles.underlineStyle} hintText="Say something.." onChange={this.handleChange} value={this.state.input} /> <RaisedButton label="Say" className="postBtn" type="submit"/> </form> </div>可以看到是主要是一个表单提交的工作,handleSubmit即表单提交的函数:
handleSubmit = (event)=>{ event.preventDefault(); if(!this.refs.input.getValue())return; this.props.postMsg(this.refs.input.getValue()); this.refs.main.scrollTop = 10000; this.setState({ input : "" }); };这里最重要的是this.props.postMsg,调用的是之前定义在action中的postMsg函数完成新增消息的操做。
到目前位置代码部分就完了,这里可以试试demo,我用的wilddog个人免费版,资源有限,别整挂了:P
基于React,Redux以及wilddog的聊天室简单实现的更多相关文章
- Android基于XMPP Smack openfire 开发的聊天室
Android基于XMPP Smack openfire 开发的聊天室(一)[会议服务.聊天室列表.加入] http://blog.csdn.net/lnb333666/article/details ...
- 实例讲解基于 React+Redux 的前端开发流程
原文地址:https://segmentfault.com/a/1190000005356568 前言:在当下的前端界,react 和 redux 发展得如火如荼,react 在 github 的 s ...
- 基于Node.js + WebSocket 的简易聊天室
代码地址如下:http://www.demodashi.com/demo/13282.html Node.js聊天室运行说明 Node.js的本质就是运行在服务端的JavaScript.Node.js ...
- 基于WebSocket和SpringBoot的群聊天室
引入 普通请求-响应方式:例如Servlet中HttpServletRequest和HttpServletResponse相互配合先接受请求.解析数据,再发出响应,处理完成后连接便断开了,没有数据的实 ...
- Java进阶:基于TCP通信的网络实时聊天室
目录 开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 ...
- C 基于UDP实现一个简易的聊天室
引言 本文是围绕Linux udp api 构建一个简易的多人聊天室.重点看思路,帮助我们加深 对udp开发中一些api了解.相对而言udp socket开发相比tcp socket开发注意的细节要少 ...
- 基于Websocket开发的仿微信聊天室
一.运行环境及涉及技术:----------------------------------* Visual Studio 2019* SQL SERVER 2008 R2* .Net FrameWo ...
- Python基于Socket实现简易多人聊天室
前言 套接字(Sockets)是双向通信信道的端点. 套接字可以在一个进程内,在同一机器上的进程之间,或者在不同主机的进程之间进行通信,主机可以是任何一台有连接互联网的机器. 套接字可以通过多种不同的 ...
- Socket.IO聊天室~简单实用
小编心语:大家过完圣诞准备迎元旦吧~小编在这里预祝大家元旦快乐!!这一次要分享的东西小编也不是很懂啊,总之小编把它拿出来是觉地比较稀奇,而且程序也没有那么难,是一个比较简单的程序,大家可以多多试试~ ...
随机推荐
- Win10连接远程桌面时提示“您的凭据不工作”
我遇到这个问题的时候查找网上都给出一堆高大上的解决办法, 然而我的错误实际上是用户名的问题, 很多人以为远程用户名就一定是锁屏状态下的登录名, 其实不是,跟自己设置有关,所以首先应该检查远程用户名是否 ...
- 如何开发FineReport的自定义控件?
FineReport作为插件化开发的报表软件,有些特殊需求的功能需要自己开发,开发的插件包帆软官方有提提供,可以去帆软论坛上找,本文将主要介绍如何开发一个自定义控件,这里讲讲方法论. 第一步:实例化一 ...
- 杂项之python描述符协议
杂项之python描述符协议 本节内容 由来 描述符协议概念 类的静态方法及类方法实现原理 类作为装饰器使用 1. 由来 闲来无事去看了看django中的内置分页方法,发现里面用到了类作为装饰器来使用 ...
- mono for android 读取网络远程图片
布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=& ...
- SQL SERVER全面优化-------Expert for SQL Server 诊断系列
现在很多用户被数据库的慢的问题所困扰,又苦于花钱请一个专业的DBA成本太高.软件维护人员对数据库的了解又不是那么深入,所以导致问题迟迟不能解决,或只能暂时解决不能得到根治.开发人员解决数据问题基本又是 ...
- java太low,又舍不得jvm平台的丰富资源?试试kotlin吧(一)
尝试kotlin的起因 因为各种原因(版权,人员招聘),公司的技术体系从c#转到了java,我花了大概两周的时间来上手java,发现java的语法还是非常简单的,基本看着代码就知道什么意思.学习jav ...
- 将自己打代码添加到cocoapods
1,Github 上创建新站点 2, 从gitHub上 clone 一份,将源码拷贝到该目录下提交3,开源库发布之后,需要打上tag git tag 0.0.1 git push --tags git ...
- 特殊的数据类型: bit、sql_variant、sysname
在SQL Server中,特殊的数据类型主要有三个,分别是:bit.sql_variant 和 sysname 一,bit bit类型,只有三个有效值:0,1 和 null,字符串true或false ...
- 前端进阶试题(css部分)
一.css 40分 1. 什么是盒模型? 答: 2. Doctype的几种类型? 答:①.过渡的:②.严格的:③.框架的 更多详细介绍参考:资料 3. 如何布局左不动右边自适应的两列布局? 答:两种简 ...
- java自定义注解类
一.前言 今天阅读帆哥代码的时候,看到了之前没有见过的新东西, 比如java自定义注解类,如何获取注解,如何反射内部类,this$0是什么意思? 于是乎,学习并整理了一下. 二.代码示例 import ...