reactjs 下拉刷新组件封装的组件怎么复用

为什么 ReactJS 不适合复杂的前端项目? - 推酷
为什么 ReactJS 不适合复杂的前端项目?
去年 4 月,我第一次在某个客户的项目中接触到ReactJS 。
我发现ReactJS要比我以前用过的AngularJS简单很多,它提供了响应式的数据绑定功能,把数据映射到网页上,使我可以轻松实现交互简单的网站。
然而,随着我越来越深入的使用ReactJS,我发现用ReactJS编写交互复杂的网页很困难。 我希望有一种方式,能够像ReactJS一样简单解决简单问题。 此外,还要能简单解决复杂问题。
于是我把ReactJS用Scala重新写了一个。代码量从近三万行降到了一千多行。
用这个框架实现的
应用,只用了152行代码。 而用ReactJS实现相同功能的TodoMVC,需要488行代码。
这个框架就是
《More than React》系列的博客会一共分为五篇和一则附录。本文是第一篇,介绍用 ReactJS开发时遇到的种种问题。后面四篇博客的每一篇将会分别详细讨论其中一个问题,以及Binding.scala如何解决这个问题。附录是一则指南,指引你从头一步步创建Binding.scala项目。
问题一:ReactJS组件难以在复杂交互页面中复用
ReactJS中的最小复用单位是组件。ReactJS的组件比AngularJS的Controller和View 要轻量些。 每个组件只需要前端开发者提供一个 render 函数,把 props 和 state 映射成网页元素。
这样的轻量级组件在渲染简单静态页面时很好用, 但是如果页面有交互,就必须在组件间传递回调函数来处理事件。 尤其是复杂的网页结构,往往需要多个组件层层嵌套,导致回调函数也必须在父子组件间层层传递, 代码变成一团乱麻,维护就很难了。
本系列博客中,组件对复用性有害?一节将用原生DHTML API、ReactJS和Binding.scala实现同一个需要复用的页面,介绍Binding.scala如何简单实现、简单复用复杂的交互逻辑。
问题二:ReactJS的虚拟DOM 算法又慢又不准
ReactJS的页面渲染算法是虚拟DOM差量算法。
开发者需要提供 render 函数,根据 props 和 state 生成虚拟 DOM。 然后 ReactJS 框架根据 render 返回的虚拟 DOM 创建相同结构的真实 DOM.
每当 state 更改时,ReacJS 框架重新调用 render 函数,获取新的虚拟 DOM 。 然后,框架会比较上次生成的虚拟 DOM 和新的虚拟 DOM 有哪些差异,然后把差异应用到真实DOM上。
这样做有两大缺点:
每次 state 更改, render 函数都要生成完整的虚拟 DOM. 哪怕 state 改动很小, render 函数也会完整计算一遍。如果 render 函数很复杂,这个过程就白白浪费了很多计算资源。
ReactJS框架比较虚拟DOM差异的过程,既慢又容易出错。比如,假如你想要在某个 &ul& 列表的顶部插入一项 &li& ,那么ReactJS框架会误以为你修改了 &ul& 的每一项 &li& ,然后在尾部插入了一个 &li& 。
这是因为 ReactJS收到的新旧两个虚拟DOM之间相互独立,ReactJS并不知道数据源发生了什么操作,只能根据新旧两个虚拟DOM来 猜测 需要执行的操作。 自动的猜测算法既不准又慢,必须要前端开发者手动提供 key 属性、 shouldComponentUpdate 方法、 componentDidUpdate 方法或者 componentWillUpdate 等方法才能帮助 ReactJS 框架猜对。
本系列博客中,虚拟DOM已死?一节将比较ReactJS、AngularJS和Binding.scala渲染机制, 介绍简单性能高的Binding.scala精确数据绑定机制。
问题三:ReactJS的HTML模板功能既不完备、也不健壮
ReactJS支持用JSX编写HTML模板。
理论上,前端工程师只要把静态HTML原型复制到JSX源文件中, 增加一些变量替换代码, 就能改造成动态页面。 理论上这种做法要比Cycle.js、Widok、ScalaTags等框架更适合复用设计师提供的HTML原型。
不幸的是,ReactJS对HTML的支持残缺不全。开发者必须手动把 class 和 for 属性替换成 className 和 htmlFor ,还要把内联的 style 样式从CSS语法改成JSON语法,代码才能运行。 这种开发方式下,前端工程师虽然可以把HTML原型复制粘贴到代码中,但还需要大量改造才能实际运行。 比Cycle.js、Widok、或者、ScalaTags省不了太多事。
除此之外,ReactJS还提供了 propTypes 机制校验虚拟DOM的合法性。 然而,这一机制也漏洞百出。 即使指定了 propTypes ,ReactJS也不能在编译前提前发现错误。只有测试覆盖率很高的项目时才能在每个组件使用其他组件时进行校验。 即使测试覆盖率很高, propTypes 仍旧不能检测出拼错的属性名,如果你把 onClick 写成了 onclick , ReactJS就不会报错,往往导致开发者额外花费大量时间排查一个很简单的bug。
本系列博客中,HTML也可以编译?一节将比较ReactJS和Binding.scala的HTML模板, 介绍Binding.scala如何在完整支持XHTML语法的同时静态检查语法错误和语义错误。
问题四:ReactJS与服务器通信时需要复杂的异步编程
ReactJS从服务器加载数据时的架构可以看成MVVM(Model–View–ViewModel)模式。 前端工程师需要编写一个数据库访问层作为Model,把ReactJS的 state 当做ViewModel,而 render 当做View。 Model负责访问数据库并把数据设置到 state (即View Model)上,可以用Promise和fetch API实现。 然后, render ,即View,负责把View Model渲染到页面上。
在这整套流程中,前端程序员需要编写大量闭包组成的异步流程, 设置、访问状态的代码五零四散, 一不小心就会bug丛生,就算小心翼翼的处理各种异步事件,也会导致程序变得复杂,既难调试,又难维护。
本系列博客中,为什么别用异步编程?一节将比较ReactJS和Binding.scala的数据同步模型, 介绍Binding.scala如何自动同步服务器数据,避免手动异步编程。
尽管Binding.scala初看上去很像ReactJS, 但隐藏在Binding.scala背后的机制更简单、更通用,与ReactJS和Widok截然不同。
所以,通过简化概念,Binding.scala灵活性更强,能用通用的方式解决ReactJS解决不了的复杂问题。
比如,除了上述四个方面以外,ReactJS的状态管理也是老大难问题,如果引入Redux或者react-router这样的第三方库来处理状态,会导致架构变复杂,分层变多,代码绕来绕去。而Binding.scala可以用和页面渲染一样的数据绑定机制描述复杂的状态,不需要任何第三方库,就能提供服务器通信、状态管理和网址分发的功能。
Binding.scala
最小复用单位
不论交互内容还是静态内容都容易复用
容易复用静态内容组件,但难以复用交互组件
页面渲染算法
精确的数据绑定
自动保证正确性
需要开发者手动设置 key 属性,不然复杂的页面会错乱。
Scala XML 字面量
是否支持 HTML 或 XHTML 语法
完整支持 XHTML
残缺支持。正常的 XHTML 无法编译。开发者必须手动把 class 和 for 属性替换成 className 和 htmlFor ,还要把内联的 style 样式从 CSS 语法改成 JSON 语法。
如何校验模板语法
自动编译时校验
运行时通过 propTypes 校验但无法检测简单的拼写错误。
服务器通讯
自动远程数据绑定
MVVM + 异步编程
如何分派网址或者锚点链接
支持把网址当成普通的绑定变量来用,无需第三方库。
不支持,需要第三方库 react-router
功能完备性
完整的前端开发解决方案
本身只包含视图部分功能。需要额外掌握 react-router 、 Redux 等第三方库才能实现完整的前端项目。
API 简单,对没用过 Scala 的人来说也很好懂
上手快。但功能太弱导致后期学习第三方库时曲线陡峭。
Binding.scala
两个多月前,我在Scala.js的论坛发布Binding.scala时,当时Scala.js社区最流行的响应式前端编程框架是
。Tim Nieradzik是Widok的作者。他在看到我发布的框架后,称赞这个框架是Scala.js社区最有前途的 HTML 5渲染框架。
他是对的,两个月后,现在Binding.scala已经成为Scala.js社区最流行的响应式前端编程框架。
我在最近的几个项目中,也逐渐放弃JavaScript和ReactJS,改用Scala.js和Binding.scala搭建新时代的前端技术栈。
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致中国领先的IT技术网站
51CTO旗下网站
ReactJS组件之间如何进行通信
React的思想还是蛮独特的,当然围绕react的一系列自动化工具也是让我感觉亚历山大。今天总结一下react组件之间的通信,权当是自己的学习笔记:reactJs中数据流向的的特点是:单项数据流
作者:易燃易爆炸来源:| 21:44
最近在学习react.js,不得不说第一次接触组件化开发很神奇,当然也很不习惯。
react的思想还是蛮独特的,当然围绕react的一系列自动化工具也是让我感觉亚历山大
今天总结一下react组件之间的通信,权当是自己的学习笔记:
reactJs中数据流向的的特点是:单项数据流
react组件之间的组合不知道为什么给我一种数据结构当中树的感觉,数据就是从根节点(顶端或其他子树的顶端)&流&下来,大概就是这个样子:
比如这是一个组件树,数据就可以从main组件流到jumbotron组件、queationList组件、form组件,类似的queation组件的数据也可以流到下边的question组件里边。
但是很遗憾,这个从上到下的数据流动,只能解决很少的问题,还有一部分的数据流动就是类似从jumbotron组件到form组件的这样的兄弟组件的流动形式,或者隔着几个层级的数据流动,再或者子组件发生了数据的变化,想通知父组件,数据流向从子组件到父组件流,这些问题才是大多数的开发者需要面临的问题。所以这篇笔记总结下基础的组件通信:
数据从父组件到子组件
最简单的通信就是父子间的通信,比如上边图上的有个jsonObj从main流进了QueationList参考代码:
//这里模拟出几条数据&var&jsonObj=[&&&&&{name:&A&,question:&从小被人打怎么办?&,TextArea:&习惯就好了&,applaud:35,disagree:1},&&&&&{name:&B&,question:&长的太帅被人砍怎么办?&,TextArea:&食屎啦你&,applaud:35,disagree:10},&&&&&{name:&C&,question:&因为太胖被人摸怎么办?&,TextArea:&享受就好了&,applaud:35,disagree:45},&&&&&{name:&D&,question:&被老师打不开心&,TextArea:&用钱打脸&,applaud:35,disagree:6},&&&&&{name:&E&,question:&不爱洗澡怎么办?&,TextArea:&打一顿就好了&,applaud:35,disagree:9}&]&&var&QuestionList=React.createClass({&&&&&prepareToRender:function(list){&&&&&&&&&var&array=[];&&&&&&&&&for(var&i=0;i&list.i++){&&&&&&&&&&&&&array.push(&Question&obj={list[i]}&&&key={i}/&);&&&&&&&&&}&&&&&&&&&return&&&&&&},&&&&&render:function(){&&&&&&&&&var&array=this.prepareToRender(this.props.jsonObj);&&&&&&&&&return&&div&{array}&/div&;&&&&&}&});&var&Main&=&React.createClass({&&&&&//开始渲染&&&&&render:&function&()&{&&&&&&&&&return&(&&&&&&&&&&&&&&div&&&&&&&&&&&&&&&&&&&div&className=&container&col-md-6&col-md-offset-3&&&&&&&&&&&&&&&&&&&&&&&&div&className=&container-fluid&&&&&&&&&&&&&&&&&&&&&&&&&&&&QuestionList&jsonObj={jsonObj}&&/&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&/div&&&&&&&&&&);&&&&&}&});&ReactDOM.render(&&&&&&Main&/&,&&&&&document.getElementById('container')&);&&
代码写的不怎么规范,但是数据的传递就是这样的:
&QuestionList jsonObj={jsonObj} /&
这样就可以把父组件的数据带到子组件里边
数据从子组件到父组件
理论上来说数据只能是单向的,所以不借助插件数据还真不好从子组件到父组件,一种很简单的手段是回调函数:
在父组件当中写个回调函数,然后传递到子组件,什么时候子组件数据变化了,直接调这个回调函数就可以了。
比如现在的jumbotron的按钮被点击了,我们想把被点击这个事件发给它的父组件也就是main组件,那么我们可以这个做:
var&Jumbotron&=&React.createClass({&&&&&handleClick:&function&()&{&&&&&&&&&this.props.openTheWindow(false);&&&&&},&&&&&render:&function&()&{&&&&&&&&&return&(&&&&&&&&&&&&&&&&&&div&className=&row&&&&&&&&&&&&&&&&&&&&&&&&div&className=&col-md-6&&col-md-offset-3&&&&&&&&&&&&&&&&&&&&&&&&&&&&button&type=&button&&className=&btn&btn-default&btn-lg&&onClick={this.handleClick}&开始体验&&&&&&&&&&&&&&&&&&&&&&&&&&/button&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&/div&&&&&&&&&&);&&&&&}&});&&var&Main&=&React.createClass({&&&&&getInitialState:&function&()&{&&&&&&&&&return&{&&&&&&&&&&&&&openTheWindow:&true&&&&&&&&&};&&&&&},&&&&&//开始给子组件一个回调函数,用来做子组件给父组件通信使用&&&&&buttonResponse:function(windowSatus){&&&&&&&&&this.setState({openTheWindow&:&windowSatus});&&&&&},&&&&&//开始渲染&&&&&render:&function&()&{&&&&&&&&&console.log(jsonObj)&&&&&&&&&return&(&&&&&&&&&&&&&&div&&&&&&&&&&&&&&&&&&&Jumbotron&openTheWindow={this.buttonResponse}/&&&&&&&&&&&&&&&/div&&&&&&&&&&);&&&&&}&});&ReactDOM.render(&&&&&&Main&/&,&&&&&document.getElementById('container')&);&&
子组件通知父组件状态变化就是这样,就好像是儿子找爸爸要零花钱,零花钱以及给不给都是爸爸说了算的。
兄弟组件之间的通信
这个其实应该是一个动态应用中最常见的通信,比如jubotron组件的点击按钮,form组件的表单出现:
这就是一个典型的兄弟之间的通信:
兄弟节点其实可以就是子父通信&&父子通信的叠加
首先按钮被点击,子组件通知负组件这个事件,然后父组件把这个消息带给另一个子组件
下边是个点击按钮显示表单的例子:
/**&&*&Created&by&niuGuangzhe&on&.&&*/&var&Jumbotron&=&React.createClass({&&&&&handleClick:&function&()&{&&&&&&&&&this.props.openTheWindow(false);&&&&&},&&&&&render:&function&()&{&&&&&&&&&return&(&&&&&&&&&&&&&&div&className=&jumbotron&&&&&&&&&&&&&&&&&&&&div&className=&row&&&&&&&&&&&&&&&&&&&&&&&&div&className=&col-md-6&&col-md-offset-3&&&&&&&&&&&&&&&&&&&&&&&&&&&&button&type=&button&&className=&btn&btn-default&btn-lg&&onClick={this.handleClick}&开始体验&&&&&&&&&&&&&&&&&&&&&&&&&&/button&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&/div&&&&&&&&&&);&&&&&}&});&&var&Form&=&React.createClass({&&&&&getInitialState:function(){&&&&&&&&&return&{&&&&&&&&&&&&&inputTitle:&请输入标题&,&&&&&&&&&&&&&mainBody:&在此输入正文&&&&&&&&&&};&&&&&},&&&&&//点击按钮触发事件:清除所有已经输入的文字&&&&&cleanText:function(){&&&&&&&&&this.setState({&&&&&&&&&&&&&inputTitle:&&,&&&&&&&&&&&&&mainBody:&&});&&&&&},&&&&&//表单监视事件&&&&&handleChange(name,e)&{&&&&&&&&&var&newState&=&{};&&&&&&&&&console.log(name);&&&&&&&&&newState[name]&=event.target.&&&&&&&&&this.setState(newState);&&&&&},&&&&&render:&function&()&{&&&&&&&&&return&(&&&&&&&&&&&&&&div&style={{display:this.props.openTheWindow?&none&:&block&}}&&&&&&&&&&&&&&&&&&&form&role=&form&&&&&&&&&&&&&&&&&&&&&&&&div&className=&form-group&&&&&&&&&&&&&&&&&&&&&&&&&&&&label&htmlFor=&title&&标题&/label&&&&&&&&&&&&&&&&&&&&&&&&&&&input&type=&text&&className=&form-control&&id=&title&&name=&inputTitle&&value={this.state.inputTitle}&onChange={this.handleChange.bind(this,&inputTitle&)}/&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&&&&&&div&className=&form-group&&&&&&&&&&&&&&&&&&&&&&&&&&&&label&htmlFor=&textArea&&正文&/label&&&&&&&&&&&&&&&&&&&&&&&&&&&textarea&className=&form-control&&rows=&3&&id=&textArea&&name=&mainBody&&value={this.state.mainBody}&onChange={this.handleChange.bind(this,&mainBody&)}&&/textarea&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&&&&&div&className=&row&&&&&&&&&&&&&&&&&&&&&&&&&&&&&input&type=&button&&className=&btn&btn-default&pull-right&leaveMeAlone&&value=&取消&&&onClick={this.cleanText}/&&&&&&&&&&&&&&&&&&&&&&&&&&&input&type=&submit&&className=&btn&btn-primary&pull-right&leaveMeAlone&&value=&提交&/&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&/form&&&&&&&&&&&&&&&/div&&&&&&&&&&)&&&&&}&})&&&var&Main&=&React.createClass({&&&&&getInitialState:&function&()&{&&&&&&&&&return&{&&&&&&&&&&&&&openTheWindow:&true&&&&&&&&&};&&&&&},&&&&&//开始给子组件一个回调函数,用来做子组件给父组件通信使用&&&&&buttonResponse:function(windowSatus){&&&&&&&&&this.setState({openTheWindow&:&windowSatus});&&&&&},&&&&&//开始渲染&&&&&render:&function&()&{&&&&&&&&&console.log(jsonObj)&&&&&&&&&return&(&&&&&&&&&&&&&&div&&&&&&&&&&&&&&&&&&&Jumbotron&openTheWindow={this.buttonResponse}/&&&&&&&&&&&&&&&&&&&div&className=&container&col-md-6&col-md-offset-3&&&&&&&&&&&&&&&&&&&&&&&&Form&openTheWindow={this.state.openTheWindow}/&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&/div&&&&&&&&&&);&&&&&}&});&ReactDOM.render(&&&&&&Main&/&,&&&&&document.getElementById('container')&);&&
就是这样,
其实上边的代码是我从之前的没事干做的一个单页面上拿过来改的,为了不出现代码无法运行的问题,下边贴出所有代码:
/**&&*&Created&by&niuGuangzhe&on&.&&*/&var&Jumbotron&=&React.createClass({&&&&&handleClick:&function&()&{&&&&&&&&&this.props.openTheWindow(false);&&&&&},&&&&&render:&function&()&{&&&&&&&&&return&(&&&&&&&&&&&&&&div&className=&jumbotron&&&&&&&&&&&&&&&&&&&&div&className=&row&&&&&&&&&&&&&&&&&&&&&&&&div&className=&col-md-6&&col-md-offset-3&&&&&&&&&&&&&&&&&&&&&&&&&&&&h2&className=&colorChange&&React+bootstrap简单实例&/h2&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&div&className=&row&&&&&&&&&&&&&&&&&&&&&&&&div&className=&col-md-6&&col-md-offset-3&&&&&&&&&&&&&&&&&&&&&&&&&&&&p&className=&colorChange&&上手体验:第一次尝试组件化开发&/p&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&div&className=&row&&&&&&&&&&&&&&&&&&&&&&&&div&className=&col-md-6&&col-md-offset-3&&&&&&&&&&&&&&&&&&&&&&&&&&&&button&type=&button&&className=&btn&btn-default&btn-lg&&onClick={this.handleClick}&开始体验&&&&&&&&&&&&&&&&&&&&&&&&&&/button&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&/div&&&&&&&&&&);&&&&&}&});&&var&Form&=&React.createClass({&&&&&getInitialState:function(){&&&&&&&&&return&{&&&&&&&&&&&&&inputTitle:&请输入标题&,&&&&&&&&&&&&&mainBody:&在此输入正文&&&&&&&&&&};&&&&&},&&&&&//点击按钮触发事件:清除所有已经输入的文字&&&&&cleanText:function(){&&&&&&&&&this.setState({&&&&&&&&&&&&&inputTitle:&&,&&&&&&&&&&&&&mainBody:&&});&&&&&},&&&&&//表单监视事件&&&&&handleChange(name,e)&{&&&&&&&&&var&newState&=&{};&&&&&&&&&console.log(name);&&&&&&&&&newState[name]&=event.target.&&&&&&&&&this.setState(newState);&&&&&},&&&&&render:&function&()&{&&&&&&&&&return&(&&&&&&&&&&&&&&div&style={{display:this.props.openTheWindow?&none&:&block&}}&&&&&&&&&&&&&&&&&&&form&role=&form&&&&&&&&&&&&&&&&&&&&&&&&div&className=&form-group&&&&&&&&&&&&&&&&&&&&&&&&&&&&label&htmlFor=&title&&标题&/label&&&&&&&&&&&&&&&&&&&&&&&&&&&input&type=&text&&className=&form-control&&id=&title&&name=&inputTitle&&value={this.state.inputTitle}&onChange={this.handleChange.bind(this,&inputTitle&)}/&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&&&&&&div&className=&form-group&&&&&&&&&&&&&&&&&&&&&&&&&&&&label&htmlFor=&textArea&&标题&/label&&&&&&&&&&&&&&&&&&&&&&&&&&&textarea&className=&form-control&&rows=&3&&id=&textArea&&name=&mainBody&&value={this.state.mainBody}&onChange={this.handleChange.bind(this,&mainBody&)}&&/textarea&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&&&&&div&className=&row&&&&&&&&&&&&&&&&&&&&&&&&&&&&&input&type=&button&&className=&btn&btn-default&pull-right&leaveMeAlone&&value=&取消&&&onClick={this.cleanText}/&&&&&&&&&&&&&&&&&&&&&&&&&&&input&type=&submit&&className=&btn&btn-primary&pull-right&leaveMeAlone&&value=&提交&/&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&/form&&&&&&&&&&&&&&&/div&&&&&&&&&&)&&&&&},&&&&&//监测从新渲染&&&&&componentDidUpdate:function(){&&&&&&&&&console.log(&子组件重新渲染;&);&&&&&}&})&&var&Question&=&React.createClass({&&&&&getInitialState&:&function(){&&&&&&&&&return&{&&&&&&&&&&&&&click:true,&&&&&&&&&&&&&disClick:true&&&&&&&&&};&&&&&},&&&&&numberHandle:function(){&&&&&&&&&if(this.state.click===true){&&&&&&&&&&&&&//奇数次点击,开始增加数据&&&&&&&&&&&&&this.props.obj.applaud+=1;&&&&&&&&&&&&&this.setState({click:false});&&&&&&&&&}else{&&&&&&&&&&&&&//偶数次点击,减去数据&&&&&&&&&&&&&this.props.obj.applaud-=1;&&&&&&&&&&&&&this.setState({click:true});&&&&&&&&&}&&&&&},&&&&&decreateHandle:function(){&&&&&&&&&if(this.state.disClick===true){&&&&&&&&&&&&&//奇数次点击,开始增加数据&&&&&&&&&&&&&this.props.obj.applaud-=1;&&&&&&&&&&&&&this.setState({disClick:false});&&&&&&&&&}else{&&&&&&&&&&&&&//偶数次点击,减去数据&&&&&&&&&&&&&this.props.obj.applaud+=1;&&&&&&&&&&&&&this.setState({disClick:true});&&&&&&&&&}&&&&&},&&&&&render:&function&()&{&&&&&&&&&return&(&&&&&&&&&&&&&&div&className=&row&leaveMe&&&&&&&&&&&&&&&&&&&&div&className=&col-md-2&&&&&&&&&&&&&&&&&&&&&&&&div&className=&col-md-12&&&&&&&&&&&&&&&&&&&&&&&&&&&&button&className=&btn&col-md-12&&&onClick={this.numberHandle}&{this.props.obj.applaud-this.props.obj.disagree}&br/&&span&&&&&&&&&&&&&&&&&&&&&&&&&&&&&className=&glyphicon&glyphicon-chevron-up&&&/span&&/button&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&&&&&span&&&/span&&&&&&&&&&&&&&&&&&&&&&&div&className=&col-md-12&&&&&&&&&&&&&&&&&&&&&&&&&&&&button&className=&btn&col-md-12&&onClick={this.decreateHandle}&&span&&&&&&&&&&&&&&&&&&&&&&&&&&&&&className=&glyphicon&glyphicon-chevron-down&&&/span&&&&&&&&&&&&&&&&&&&&&&&&&&&/button&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&div&className=&col-md-10&&bs-callout&bs-callout-info&&&&&&&&&&&&&&&&&&&&&&&&h4&{this.props.obj.question}&/h4&&&&&&&&&&&&&&&&&&&&&&&p&{this.props.obj.TextArea}&/p&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&/div&&&&&&&&&&);&&&&&}&});&&var&QuestionList=React.createClass({&&&&&prepareToRender:function(list){&&&&&&&&&var&array=[];&&&&&&&&&for(var&i=0;i&list.i++){&&&&&&&&&&&&&array.push(&Question&obj={list[i]}&&&key={i}/&);&&&&&&&&&}&&&&&&&&&return&&&&&&},&&&&&render:function(){&&&&&&&&&var&array=this.prepareToRender(this.props.jsonObj);&&&&&&&&&return&&div&{array}&/div&;&&&&&}&});&&&//这里模拟出几条数据&var&jsonObj=[&&&&&{name:&A&,question:&从小被人打怎么办?&,TextArea:&习惯就好了&,applaud:35,disagree:1},&&&&&{name:&B&,question:&长的太帅被人砍怎么办?&,TextArea:&食屎啦你&,applaud:35,disagree:10},&&&&&{name:&C&,question:&因为太胖被人摸奶怎么办?&,TextArea:&享受就好了&,applaud:35,disagree:45},&&&&&{name:&D&,question:&被老师打不开心&,TextArea:&用钱打ta脸&,applaud:35,disagree:6},&&&&&{name:&E&,question:&不爱洗澡怎么办?&,TextArea:&打一顿就好了&,applaud:35,disagree:9}&]&&var&Main&=&React.createClass({&&&&&getInitialState:&function&()&{&&&&&&&&&return&{&&&&&&&&&&&&&openTheWindow:&true&&&&&&&&&};&&&&&},&&&&&//开始给子组件一个回调函数,用来做子组件给父组件通信使用&&&&&buttonResponse:function(windowSatus){&&&&&&&&&this.setState({openTheWindow&:&windowSatus});&&&&&},&&&&&//开始渲染&&&&&render:&function&()&{&&&&&&&&&console.log(jsonObj)&&&&&&&&&return&(&&&&&&&&&&&&&&div&&&&&&&&&&&&&&&&&&&Jumbotron&openTheWindow={this.buttonResponse}/&&&&&&&&&&&&&&&&&&&div&className=&container&col-md-6&col-md-offset-3&&&&&&&&&&&&&&&&&&&&&&&&Form&openTheWindow={this.state.openTheWindow}/&&&&&&&&&&&&&&&&&&&&&&&br/&&br/&&&&&&&&&&&&&&&&&&&&&&&div&className=&container-fluid&&&&&&&&&&&&&&&&&&&&&&&&&&&&QuestionList&jsonObj={jsonObj}&&/&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&/div&&&&&&&&&&);&&&&&},&//&&&&执行hook函数:重新渲染完成的时候调这个函数&&&&&componentDidUpdate:function(){&&&&&&&&&console.log(this.state.openTheWindow);&&&&&}&});&ReactDOM.render(&&&&&&Main&/&,&&&&&document.getElementById('container')&);&&
最后就是一个很重要的问题:就是多层级的据数据传输,如果还用这个方式来传播的话,效率貌似是个大问题,解决办法看大家的做法目前暂时还是flux之类的其他框架,等研究出来单独写篇文章吧
【编辑推荐】
【责任编辑: TEL:(010)】
大家都在看猜你喜欢
专题头条原创头条原创
24H热文一周话题本月最赞
讲师:1人学习过
讲师:24人学习过
讲师:0人学习过
精选博文论坛热帖下载排行
随着互联网的迅速发展,几乎所有工具软件和程序语言都支持的正则表达式也变得越来越强大和易于使用。本书是讲解正则表达式的经典之作。本书...
订阅51CTO邮刊}

我要回帖

更多关于 reactjs 日期选择组件 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信