爱彼机械表走时误差标准

15:19:31 UTC
除了用refs一个一个写以外,有没有方便一点的办法
15:21:36 UTC
使用,不过他最近快要release新版本了,API有巨大变化,可以关注一下新版本,等release了再用
16:29:27 UTC
推荐使用受控表单,给表单元素 input 等添加 onChange 事件,更改对应的 state,这个过程可以添加数据验证。
推荐阅读: 注:这篇文章将原文的 Controlled Components 翻译为受限组件,我认为翻译为受控组件更合适一些。Or
15:55:01 UTC
刚写了一点React UI Form设计的文字,可以参考下:)
07:28:52 UTC
var React = require('react');
var ReactDOM = require('react-dom');
var {Form, Input} = require('react-form');
var {Password, Text} = require('react-form-inputs');
var LoginForm = React.createClass({
render() {
&Form {...this.props} for="user"&
&h1&Login&/h1&
&Input type={Text} for="username" placeholder="Username" /&
&Input type={Password} for="password" placeholder="Password" /&
&input type="submit" value="Login" /&
var user = {
username: null,
password: null
ReactDOM.render(&LoginForm object={user} /&, document.getElementById('example'));
browserify -t browserify-jsx
form.jsError: Parsing file form.js: Unexpected token (10:0) 这个写法怎么转换?更多公众号:gh_ff02f1bc28ce一起奋斗,创业之家最新文章相关作者文章搜狗:感谢您阅读React.js学习笔记之表单详解 本文版权归原作者所有,本文由网友投递产生,如有侵权请联系 ,会第一时间为您处理删除。react和react-native代码类(12)
const AddMaintainPerson = Form.create()(React.createClass({
getInitialState() {
passwordDirty: false
* 表单提交的内容
* @param e
handleSubmit(e) {
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) =& {
if (!err) {
console.log(values);
console.log('Received values of form: ', values);
var managerJson={
&phone&: values.phone,
&email&: values.email,
&username&: values.username,
&password&: values.password,
&role&:values.role
const {dispatch} = this.props;
dispatch(fetchAddMaintain('token',managerJson));
//提交成功之后清空数据
this.props.form.resetFields();
获取密码框中鼠标的焦点
* @param e
handlePasswordBlur(e) {
const value = e.target.value;
this.setState({ passwordDirty: this.state.passwordDirty || !!value });
验证两次输入的密码
* @param rule
* @param value
* @param callback
checkPassword(rule, value, callback) {
const form = this.props.form;
if (value && value !== form.getFieldValue('password')) {
callback('两次密码输入不一致!');
callback();
验证密码是否为空
* @param rule
* @param value
* @param callback
checkConfirm(rule, value, callback) {
const form = this.props.form;
if (value && this.state.passwordDirty) {
form.validateFields(['confirm'], { force: true });
callback();
render() {
const { getFieldDecorator } = this.props.form;
//设置加载formItemLayout(输入框,单选按钮,多选框,进度条)的样式
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 9 }
//设置加载tailFormItemLayout(提交按钮)的样式
const tailFormItemLayout = {
wrapperCol: {
//defaultValue={['唱歌']}
设置多选框的默认值
&div className=&body_div&&
&div className='module_header'&
&div className='title'&
&div className='module_content' style={{width:'70%'}}&
&Form onSubmit={this.handleSubmit}&
{...formItemLayout}
label=&手机号&
{getFieldDecorator('phone', {
required: true, message: '请输入您的手机号!'
&Input className=&content_style& addonBefore={&Icon type=&mobile& /&} /&
&/FormItem&
{...formItemLayout}
label=&邮箱&
hasFeedback
{getFieldDecorator('email', {
type: 'email', message: '输入邮箱的类型错误'
required: true, message: '请输入您的邮箱'
&Input className=&content_style& addonBefore={&Icon type=&mail& /&} /&
&/FormItem&
{...formItemLayout}
label=&账号&
{getFieldDecorator('username', {
rules: [{ required: true, message: '请输入您的账号' }]
&Input className=&content_style& addonBefore={&Icon type=&user& /&} /&
&/FormItem&
{...formItemLayout}
label=&密码&
hasFeedback
{getFieldDecorator('password', {
required: true, message: '请输入您的密码'
validator: this.checkConfirm
&Input className=&content_style& addonBefore={&Icon type=&lock& /&} type=&password& onBlur={this.handlePasswordBlur} /&
&/FormItem&
{...formItemLayout}
label=&确认密码&
hasFeedback
{getFieldDecorator('confirm', {
required: true, message: '请在次输入您的密码'
validator: this.checkPassword
&Input className=&content_style& addonBefore={&Icon type=&lock& /&} type=&password& /&
&/FormItem&
{...formItemLayout}
label=&权限&
{getFieldDecorator('role',{
rules: [{ required: true, message: '请选择您的权限' }]
&RadioGroup className=&content_style&&
&Radio value=&上传&&上传&/Radio&
&Radio value=&审核&&审核&/Radio&
&Radio value=&审核查询&&审核查询&/Radio&
&Radio value=&统计查询&&统计查询&/Radio&
&/RadioGroup&
&/FormItem&
&FormItem {...tailFormItemLayout}&
&Button type=&primary& htmlType=&submit& size=&large&&提交&/Button&
&/FormItem&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2513次
排名:千里之外
原创:27篇
转载:17篇
(18)(12)(17)966,690 四月 独立访问用户
语言 & 开发
架构 & 设计
文化 & 方法
您目前处于:
让React组件变得可响应
让React组件变得可响应
日. 估计阅读时间:
道AI风控、Serverless架构、EB级存储引擎,尽在!
我们将创建的Snapterest是一个Web应用程序,它会实时接收来自Snapkite引擎服务器的推文,并将推文逐条显示给用户。虽然我们不知道Snapterest会在什么时候收到一条新推文,但是当新推文到达时,它至少应该显示1.5秒钟以便用户有足够的时间看到并点击它。点击推文会将它添加到一个现有的推文集合或者创建一个新的集合。最终用户能够将集合导出为一段HTML代码。
对于我们正在构建的应用,上述描述非常笼统。让我们把它分解成更小的任务,如下图:
实时地从Snapkite引擎服务器接收推文。
每条推文至少显示1.5秒。
通过用户的点击事件将推文添加到一个集合中。
显示集合中的推文。
为集合创建HTML代码并导出。
通过用户点击事件从集合中移除推文。
相关厂商内容
相关赞助商
ArchSummit深圳-8日,深圳&华侨城洲际酒店,
你可以确定哪些任务能使用React解决吗?记住React是一个用户界面库,因此,任何与用户界面或用户界面交互相关的任务都可以使用React解决。在前面的列表中,除了第一个任务外,其他的任务React都能胜任,因为第一个任务描述的是数据获取,与用户界面毫无关系。任务1将会使用其他库来解决,我们将在下一章讨论。任务2和任务4描述的内容是需要被显示的,React组件是最合适的选择。任务3和任务6描述的是用户事件,如我们在第3章所介绍的,用户事件处理可以被很好地封装在React组件中。任务5怎样使用React来解决呢?第2章我们讨论过ReactDOMServer.renderToStaticMarkup()方法能将React元素渲染成静态的HTML标记字符串,这正是我们解决任务5所需的方案。
现在我们已经为每一个任务确定了潜在的解决方案,让我们思考一下我们将要怎么把它们结合在一起来创建一个功能全面的Web应用程序。
有两种方法来创建可组合的React应用:
先构建单个的React组件,然后将它们组合起来形成更高层级的React组件,自底向上来构建层级。
从最顶级的React元素开始,然后实现它的子组件,自顶向下来构建层级。
从观察和理解应用架构的角度来看,第二种策略更有优势。我认为在考虑各个部分的功能如何实现之前,先了解所有组件如何组合在一起更重要。
2. 规划React应用程序
规划React应用时应遵循下面两条简单的原则:
每个React组件应该代表一个用户界面元素。它应该封装最小的可复用元素。
多个React组件应该组成一个独立的React组件。最终,整个用户页面应该封装成一个React组件。
参见下图,先从最上层的React组件Application开始。它将封装我们的整个React应用程序,它有两个子组件:Stream和Collection。Stream组件将负责连接到一个消息流,接收和显示最新的消息。Stream组件有两个子组件:StreamTweet和Header。StreamTweet组件将负责显示最新的消息,它由Header和Tweet组合而成。Header组件将会渲染头部,它没有子组件。Tweet组件会渲染来自推文的一张图片。注意我们已经可以复用Header组件两次了。
我们的React组件的层次图
Collection组件负责显示收集控件和推文列表。它有两个子组件:CollectionControls和tweetlist。前者又有两个子组件:Collection RenameForm组件将渲染一个表单,用来重命名集合;CollectionExportForm组件将渲染一个表单,用来将集合导出到一个叫作CodePen的服务,这是一个HTML、CSS和JavaScript的演示网站,可以在上了解更多关于Codepen的信息。你可能已经注意到,我们将在CollectionFenameForm和CollectionControls组件中复用Header和Button组件。TweetList组件将渲染一个推文列表。每一条推文将被渲染成一个Tweet组件。在Collection组件中,我们将再次复用Header组件。事实上,我们总共要复用5次Header组件。这对我们来说能省很大事。正如我们在前一章中讨论的,我们应该尽可能保持更多组件是无状态的。因此,总共11个组件中只有下面5个组件存储状态:
Application
CollectionControls
CollectionRenameForm
?StreamTweet
有了规划之后,我们开始实现吧。
3. 创建一个React组件容器
让我们首先编辑应用程序的JavaScript主文件,使用下面的代码片段替换~/snapterest/source/app.js文件内容:var React = require('react');
var ReactDOM = require('react-dom');
var Application = require('./components/Application.react');
ReactDOM.render(&Application /&,
document.getElementById('react-
application'));
这个文件仅有四行代码,实现的是:将document.getElementById('react- application') 作为组件的部署目标,并将Application组件渲染到DOM中。Web应用程序的整个用户界面都将被封装在这个组件中。
接下来,切换到~/snapterest/source/components/目录并创建Applica tion.react.js文件。我们约定所有React组件的文件名都以react.js结尾,这样我们就可以很轻意地分辨React与非React文件。
让我们看一下Application.react.js文件的内容:var React = require('react');
var Stream = require('./Stream.react');
var Collection = require('./Collection.react');
var Application = React.createClass({
getInitialState: function() {
collectionTweets: {}
addTweetToCollection: function(tweet) {
var collectionTweets = this.state.collectionT
collectionTweets[tweet.id] =
this.setState({
collectionTweets: collectionTweets
removeTweetFromCollection: function(tweet) {
var collectionTweets = this.state.collectionT
delete collectionTweets[tweet.id];
this.setState({
collectionTweets: collectionTweets
removeAllTweetsFromCollection: function() {
var collectionTweets = this.state.collectionT
delete collectionTweets[tweet.id];
this.setState({
collectionTweets: {}
removeAllTweetsFromCollection: function () {
this.setState({
collectionTweets: {}
render: function() {
&div className="container-fluid"&
&div className="row"&
&div className="col-md-4 text-center"&
&Stream onAddTweetToCollection={this.addTweetToCollection} /&
&div className="col-md-8"&
&Collection
tweets={this.state.collectionTweets}
onRemoveTweetFromCollection={this.
removeTweetFromCollection}
onRemoveAllTweetsFromCollection={this.
removeAllTweetsFromCollection}/&
module.exports = A
这个组件的代码比app.js多了很多,但是这些代码可以很容易地分为三个逻辑部分:
引入依赖模块
定义React组件
作为模块导出这个React组件
大多数React组件中都可以看到这样的逻辑分割,因为包装成CommonJS模块才能使用Browserify引入它们。事实上,这个源文件的第一部分和第三部分的写法都是CommonJS规定的,与React无关。使用这种模块规范的目的是将应用程序分解成模块以便复用。因为React组件和CommonJS模块都可以封装代码并使代码更灵活,所以它们在一起自然可以很好地工作。将最终的用户界面逻辑封装在一个CommonJS模块形式的React组件中,其他模块就可以复用这个被封装好的React组件了。
Application.react.js文件的引入逻辑使用require()函数引入了依赖模块:var React = require('react');
var Stream = require('./Stream.react');
var Collection = require('./Collection.react');
这里Application组件引入了下面两个子组件:
Stream组件将在用户界面中渲染信息流部分。
Collection组件将在用户页面中渲染集合部分。
我们也需要引入React库,但这部分代码都是按照CommonJS模块规范编写的,与React本身无关。
Application.react.js文件的第二部分逻辑创建带有以下方法的ReactApp licaton组件:
getInitialState()
addTweetToCollection()
removeTweetFromCollection()
removeAllTweetsFromCollection()
只有getInitialState()和render()方法是React API,其他方法都是这个组件封装的应用程序逻辑的一部分。讨论完这个组件的render()方法会渲染什么内容之后,我们再仔细分析每个逻辑方法:render: function () {
&div className="container-fluid"&
&div className="row"&
&div className="col-md-4 text-center"&
&Stream onAddTweetToCollection={this.addTweetToCollection} /&
&div className="col-md-8"&
&Collection
tweets={this.state.collectionTweets}
onRemoveTweetFromCollection={this.
removeTweetFromCollection}
onRemoveAllTweetsFromCollection={this.
removeAllTweetsFromCollection} /&
这段代码使用Bootstrap框架定义了网页布局。如果你不熟悉Bootstrap,我强烈推荐你访问上的文档。掌握了这个框架你就能用最快的速度和最简单的方法搭建用户界面原型。不过即使你不知道Bootstrap,也不影响理解后面的内容。我们将网页划分为两列:一个小的和一个大的。小的包含Stream组件,大的包含Collection组件。可以想象我们的网页被划分成两个不等的部分,它们都包含React组件。
我们这样使用Stream组件:
&Stream onAddTweetToCollection={this.addTweetToCollection} /&
Stream组件有一个onAddTweetToCollection属性,Application组件将自己的addTweetToCollection()函数作为这个属性的值。addTweetTocollection()函数会添加一条推文到集合中。这是Applicaton组件中的一个自定义方法,我们可以用this关键字来引用它。
让我们看一下addTweetToCollection()做了什么:addTweetToCollection: function (tweet) {
var collectionTweets = this.state.collectionT
collectionTweets[tweet.id] =
this.setState({
collectionTweets: collectionTweets
&div class="md-section-divider"&&/div&
这个函数引用存储在当前state中的CollectionTweets,添加一条新推文到CollectonTweets对象,并通过调用setState()函数来更新state。在Stream组件中,当addTweetToCollection()函数被调用时,一条新推文会作为参数被传入。这是一个子组件更新其父组件state的例子。
这是React的一个重要机制,它的工作过程如下。
父组件传递一个回调函数作为子组件的属性。子组件可以通过this.props变量访问这个回调函数。
每当子组件想要更新父组件的state时,它就会调用这个回调函数并传递所有必要的数据到父组件的新状态中。
父组件更新它的state,而且state更新会触发render()函数重新渲染所有必要的子组件。
这就是React中父组件与子组件的交互机制。这个机制允许子组件将应用程序状态管理委托到它的父组件,子组件只需要关心如何渲染自己就行了。了解了这个机制之后,我们还将多次使用它,因为大部分React组件要保持无状态。应该只有少量的父组件负责存储和管理应用程序的state。这个最佳实践允许我们按照以下两个不同的关注点来有序地组织React组件:
管理应用程序的state和渲染。
只关注渲染并且将应用程序的state管理委托到父组件上。
Application组件的第二个子组件Collection如下:&Collection
tweets={this.state.collectionTweets}
onRemoveTweetFromCollection={this.removeTweetFromCollection}
onRemoveAllTweetsFromCollection={this.removeAllTweetsFromCollection}
&div class="md-section-divider"&&/div&
这个组件有如下一些属性。
tweets:引用当前推文集合。
onRemoveTweetFromCollection:这个函数从集合中删除特定的推文
onRemoveAllTweetFromCollection:这个函数从集合中删除所有的推文。
Collection组件的属性仅仅关注下面两点:
如何访问应用程序的state。
如何改变应用程序的state。
显然,onRemoveTweetFromCollection和onRemoveAllTweetsFromCollection函数允许Collection组件改变Application组件的state。另一方面,tweets属性把Application组件的state传递给Collection组件,使Collection组件获得访问state的只读权限。
你能觉察到在Application和Collection组件之间的数据的单向流动吗?以下是它的工作过程:
使用Application组件的getInitalState()方法初始化collection Tweets数据。
collectionTweets数据作为tweets属性传递给Collection组件。
Collection组件调用removeTweetFromCollection和removeAllTweet FromCollection,更新Application中的collectionTweets数据,然后再次开始循环。
注意,Collection组件不能直接改变Application组件的state。Collection组件有通过this.props对象访问state的只读权限,并仅可以通过调用父组件传递的回调函数来更新父组件的state。在Collection组件中,这些回调函数是this.props.onRemoveTweetFromCollection和this.props.onRemoveAllTweetFrom Collection。
在React组件层次中,这种数据流动的简单思维模型有助于增加组件的数量,而不增加用户页面的复杂性。比如,它可以有10个层级的React组件嵌套,如下图所示。
在这个层次结构中,如果组件G要改变根组件A的state,其所用的方法与组件B、组件F或者其他任何组件使用的方法完全相同。然而,在React中,你不应该将数据直接从组件A传递到组件G。相反,你首先可以把它传递给组件B,然后给组件C,然后给组件D,依此类推,直至组件G。组件B到组件F必须携带一些transit属性,这些属性实际上只对组件G有用。这看起来可能是在浪费时间,但是这个设计使我们更容易调试应用程序,并可以推理出它是如何工作的。想优化应用程序的架构总是有办法的。Flux就是一种优化方案,本书后面会讨论它。
最后,再看一下改变Application的state的两个方法:removeTweetFromCollection: function (tweet) {
var collectionTweets = this.state.collectionT
delete collectionTweets[tweet.id];
this.setState({
collectionTweets: collectionTweets
&div class="md-section-divider"&&/div&
removeTweetFromCollection()方法从存储在Application组件的推文集合中移除一条推文,它需要从组件的state中得到当前的collectionTweet对象,然后根据给定的ID从state对象中删除一条推文,并使用一个新的collectionTweets对象来更新组件的state。
此外removeAllTweetsFromCollection()方法会从组件state中移除所有推文:removeAllTweetsFromCollection: function () {
this.setState({
collectionTweets: {}
这些方法都是在子组件Collection中调用的,因为该组件没有其他方法可以改变Application组件的state。
在这一章中,我们学习了如何使用React解决问题。我们首先把问题分解成一些小问题,并讨论了如何使用React解决它们。然后,创建一些需要实现的React组件。最后,我们创建了第一个可组合的React组件,并学习了如何让父组件与它的子组件交互。在下一章,我们将实现我们的子组件并学习React生命周期相关的方法。
《React 精髓》面向初中级前端开发者,从头到尾、由浅入深地介绍了使用React 实现组件化Web 应用的完整流程。作者从React 元素、React 组件等基本的概念讲起,循序渐进地讨论了组件状态和生命周期,为开发完整的React 应用打下了基础。与第三方JavaScript 框架集成,以及对React 组件进行单元测试,都是开发React 应用的重要内容,《React 精髓》也有详细讲解。最后,为进一步提升React 应用的灵活性,作者还以实例展示了如何引入Flux 架构,让读者的开发技能更上一层楼。
Author Contacted
告诉我们您的想法
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
赞助商链接
InfoQ每周精要
订阅InfoQ每周精要,加入拥有25万多名资深开发者的庞大技术社区。
架构 & 设计
文化 & 方法
<及所有内容,版权所有 &#169;
C4Media Inc.
服务器由 提供, 我们最信赖的ISP伙伴。
北京创新网媒广告有限公司
京ICP备号-7
注意:如果要修改您的邮箱,我们将会发送确认邮件到您原来的邮箱。
使用现有的公司名称
修改公司名称为:
公司性质:
使用现有的公司性质
修改公司性质为:
使用现有的公司规模
修改公司规模为:
使用现在的国家
使用现在的省份
Subscribe to our newsletter?
Subscribe to our industry email notices?
我们发现您在使用ad blocker。
我们理解您使用ad blocker的初衷,但为了保证InfoQ能够继续以免费方式为您服务,我们需要您的支持。InfoQ绝不会在未经您许可的情况下将您的数据提供给第三方。我们仅将其用于向读者发送相关广告内容。请您将InfoQ添加至白名单,感谢您的理解与支持。

我要回帖

更多关于 爱彼手表维修点 的文章

 

随机推荐