Your first component
React is all about modular, composable components. For our comment box example, we'll have the following component structure:
你的第一个组件
React全部是是关于模块化、可组装的组件的。对于我们的评论框例子,我们需要下面的组件结构:
- CommentList - CommentForm
Let's build the CommentBox
component, which is just a simple <div>
:
var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> Hello, world! I am a CommentBox. </div> ); } }); React.render( <CommentBox />, document.getElementById('content') );
创建CommentBox组件,只是一个<div>
JSX Syntax
The first thing you'll notice is the XML-ish syntax in your JavaScript. We have a simple precompiler that translates the syntactic sugar to this plain JavaScript:
JSX语法
在你的js中,你会注意到类似XML的语法。我们有一个简单的预编译器,可以将语法糖转化成js
var CommentBox = React.createClass({displayName: 'CommentBox', render: function() { return ( React.createElement('div', {className: "commentBox"}, "Hello, world! I am a CommentBox." ) ); } }); React.render( React.createElement(CommentBox, null), document.getElementById('content') );
Its use is optional but we've found JSX syntax easier to use than plain JavaScript.
JSX语法比JS更好用。
What's going on
We pass some methods in a JavaScript object to React.createClass()
to create a new React component. The most important of these methods is called render
which returns a tree of React components that will eventually render to HTML.
The <div>
tags are not actual DOM nodes; they are instantiations of React div
components. You can think of these as markers or pieces of data that React knows how to handle. React issafe. We are not generating HTML strings so XSS protection is the default.
You do not have to return basic HTML. You can return a tree of components that you (or someone else) built. This is what makes React composable: a key tenet of maintainable frontends.
React.render()
instantiates the root component, starts the framework, and injects the markup into a raw DOM element, provided as the second argument.
代码运行原理
我们把js对象中的一些方法传递给react.createClass(),来创建一个新的react组件。这些方法中最重要的是render,它返回react组件树,这棵树最终渲染成HTML。<div>标签不是真正的DOM节点,他们是react div 组件的实例。你可以把他们作为一些标记或者数据,react知道如何处理。react是安全的,我们不生成HTML,所以默认提供防xss保护。你不必返回HTML,你可以返回你创建的组件树。这令react组件化:前端可维护性的关键一点。react.render()实例化根组件,开启框架,将标记注入DOM元素,作为第二个参数提供。
Composing components
Let's build skeletons for CommentList
and CommentForm
which will, again, be simple <div>
s:
制作组件
让我们制作commentList和commentForm的框架,还是简单的<div>
var CommentList = React.createClass({ render: function() { return ( <div className="commentList"> Hello, world! I am a CommentList. </div> ); } }); var CommentForm = React.createClass({ render: function() { return ( <div className="commentForm"> Hello, world! I am a CommentForm. </div> ); } });
Next, update the CommentBox
component to use these new components:
下一步,更新commentBox组件,来应用这些新的组件
var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList /> <CommentForm /> </div> ); } });
Notice how we're mixing HTML tags and components we've built. HTML components are regular React components, just like the ones you define, with one difference. The JSX compiler will automatically rewrite HTML tags to React.createElement(tagName)
expressions and leave everything else alone. This is to prevent the pollution of the global namespace.
注意我们是如何将HTML和组件融合的。HTML组件是常规的react组件,就像你定义的那些,只有一点不同。JSX编译器自动把HTML重写为react.createElement()表达式,保持其他不变。这防止了全局命名空间的污染。
Using props
Let's create the Comment
component, which will depend on data passed in from it's parent. Data passed in from a parent component is available as a 'property' on the child component. These 'properties' are accessed through this.props
. Using props we will be able to read the data passed to the Comment
from the CommentList
, and render some markup:
使用props
让我们创建comment 组件,它取决于从父节点传入的数据。从父组件传入的数据对子组件来说是属性。这些属性通过this.props读取。使用props我们可以读取从commentList传递给comment的数据,并且渲染一些标记。
var Comment = React.createClass({ render: function() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> {this.props.children} </div> ); } });
By surrounding a JavaScript expression in braces inside JSX (as either an attribute or child), you can drop text or React components into the tree. We access named attributes passed to the component as keys on this.props
and any nested elements as this.props.children
.
把一个js语句放入在JSX中的括号中,你可以将text和react components放入树中。我们将传递给组件的属性作为this.props的键,将嵌套的元素作为this.props.children
Component Properties
Now that we have defined the Comment
component, we will want to pass it the author name and comment text. This allows us to reuse the same code for each unique comment. Now let's add some comments within our CommentList
:
组件属性
我们定义了comment组件,我们想向他传递作者姓名和评论内容。这让我们可以为每一条单独的评论重用相同的代码。现在,让我们在commentList中添加一些评论。
var CommentList = React.createClass({ render: function() { return ( <div className="commentList"> <Comment author="Pete Hunt">This is one comment</Comment> <Comment author="Jordan Walke">This is *another* comment</Comment> </div> ); } });
Note that we have passed some data from the parent CommentList
component to the childComment
components. For example, we passed Pete Hunt (via an attribute) and This is one comment (via an XML-like child node) to the first Comment
. As noted above, the Comment
component will access these 'properties' through this.props.author
, andthis.props.children
.
注意,我们从父组件commentList中传递一些数据给子组件comment。例如,我们传递Pete和this is one comment给第一个comment。如上所示,comment组件会读取这些属性,通过this.props.author和this.props.children
Adding Markdown
Markdown is a simple way to format your text inline. For example, surrounding text with asterisks will make it emphasized.
First, add the third-party Showdown library to your application. This is a JavaScript library which takes Markdown text and converts it to raw HTML. This requires a script tag in your head (which we have already included in the React playground):
添加markdown
markdown是一个简单的方式来在行中格式化文本。例如,