本文主要是使用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的聊天室简单实现的更多相关文章

  1. Android基于XMPP Smack openfire 开发的聊天室

    Android基于XMPP Smack openfire 开发的聊天室(一)[会议服务.聊天室列表.加入] http://blog.csdn.net/lnb333666/article/details ...

  2. 实例讲解基于 React+Redux 的前端开发流程

    原文地址:https://segmentfault.com/a/1190000005356568 前言:在当下的前端界,react 和 redux 发展得如火如荼,react 在 github 的 s ...

  3. 基于Node.js + WebSocket 的简易聊天室

    代码地址如下:http://www.demodashi.com/demo/13282.html Node.js聊天室运行说明 Node.js的本质就是运行在服务端的JavaScript.Node.js ...

  4. 基于WebSocket和SpringBoot的群聊天室

    引入 普通请求-响应方式:例如Servlet中HttpServletRequest和HttpServletResponse相互配合先接受请求.解析数据,再发出响应,处理完成后连接便断开了,没有数据的实 ...

  5. Java进阶:基于TCP通信的网络实时聊天室

    目录 开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 ...

  6. C 基于UDP实现一个简易的聊天室

    引言 本文是围绕Linux udp api 构建一个简易的多人聊天室.重点看思路,帮助我们加深 对udp开发中一些api了解.相对而言udp socket开发相比tcp socket开发注意的细节要少 ...

  7. 基于Websocket开发的仿微信聊天室

    一.运行环境及涉及技术:----------------------------------* Visual Studio 2019* SQL SERVER 2008 R2* .Net FrameWo ...

  8. Python基于Socket实现简易多人聊天室

    前言 套接字(Sockets)是双向通信信道的端点. 套接字可以在一个进程内,在同一机器上的进程之间,或者在不同主机的进程之间进行通信,主机可以是任何一台有连接互联网的机器. 套接字可以通过多种不同的 ...

  9. Socket.IO聊天室~简单实用

    小编心语:大家过完圣诞准备迎元旦吧~小编在这里预祝大家元旦快乐!!这一次要分享的东西小编也不是很懂啊,总之小编把它拿出来是觉地比较稀奇,而且程序也没有那么难,是一个比较简单的程序,大家可以多多试试~ ...

随机推荐

  1. 图解Spark API

    初识spark,需要对其API有熟悉的了解才能方便开发上层应用.本文用图形的方式直观表达相关API的工作特点,并提供了解新的API接口使用的方法.例子代码全部使用python实现. 1. 数据源准备 ...

  2. linux启动SSH及开机自动启动

    本文地址 分享提纲: 1.查看是否启动 2. 设置自动启动 1.[查看是否启动] 启动SSH服务 “/etc/init.d/sshd start”.然后用netstat -antulp | grep ...

  3. Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录

    一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...

  4. Android快乐贪吃蛇游戏实战项目开发教程-06虚拟方向键(五)绘制方向键箭头

    本系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html本系列教程项目源码GitHub地址:https://github.com/jack ...

  5. iOS 4s-6Plus屏幕自动适配及颜色转换为十六进制

    iOS各种屏幕自动适配及颜色转换为十六进制 ★★★XLJMatchScreen自动适配屏幕★★★ 支持pod导入 pod 'XLJScreenMatching', '~> 1.0.3' 如果发现 ...

  6. mako模板调试与使用技巧

    django默认的模板太不灵活,想把一个数字0.15显示成15%都得费不少劲,太不爽!!! 网上查阅了几个模板系统,有Jinja2等等,最后发现mako能够直接支持python的语句,最为灵活,果断选 ...

  7. Android WebView 优化页面加载效果

    目前带有Web功能的APP越来越多,为了能够更好的使用WebView展示页面,可以考虑做相关的优化:WebView 缓存,资源文件本地存储,客户端UI优化. 可能有些人会说,为什么不做Native的, ...

  8. undefined

    概述 undefined有多重角色,通常情况下,我们所说的undefined都指的是全局对象的一个属性"undefined". 语法 undefined 描述 在JavaScrip ...

  9. html5中canvas的使用 获取鼠标点击页面上某点的RGB

    1.html5中的canvas在IE9中可以跑起来.在IE8则跑不起来,这时候就需要一些东西了. 我推荐这种方法,这样显得代码不乱. <!--[if lt IE9]> <script ...

  10. nginx源码分析之hash的实现

    nginx实现了自己的hash数据结构,正如数据结构中讲述的那样,nginx用开放链表法解决冲突,不过不同的是一旦一个hash表被初始化后就不会被修改,即插入和删除,只进行查询操作,所以nginx通过 ...