添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
道上混的稀饭  ·  中国这十年_新华网·  1 年前    · 
我去  ·  svn - Repository has ...·  5 年前    · 

下面,我就根据 这个库 ,写一篇全面又易懂的 React 入门教程。你只需要跟着每一个 Demo 做一遍,就能初步掌握 React 。当然,前提是你必须拥有基本 JavaScript 和 DOM 知识,但是你读完就会发现,React 所要求的预备知识真的很少。

React 的安装包,可以到 官网 下载。不过, React Demos 已经自带 React 源码,不用另外安装,只需把这个库拷贝到你的硬盘就行了。

$ git clone [email protected] :ruanyf/react-demos.git

如果你没安装 git, 那就直接下载 zip 压缩包

下面要讲解的12个例子在各个 Demo 子目录,每个目录都有一个 index.html 文件,在浏览器打开这个文件(大多数情况下双击即可),就能立刻看到效果。

需要说明的是,React 可以在浏览器运行,也可以在服务器运行,但是本教程只涉及浏览器。一方面是为了尽量保持简单,另一方面 React 的语法是一致的,服务器的用法与浏览器差别不大。 Demo13 是服务器首屏渲染的例子,有兴趣的朋友可以自己去看源码。

一、HTML 模板

使用 React 的网页源码,结构大致如下。

<!DOCTYPE html> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <div id="example"></div> <script type="text/babel"> // ** Our code goes here! ** </script> </body> </html>

上面代码有两个地方需要注意。首先,最后一个 <script> 标签的 type 属性为 text/babel 。这是因为 React 独有的 JSX 语法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type="text/babel"

其次,上面代码一共用了三个库: react.js react-dom.js Browser.js ,它们必须首先加载。其中, react.js 是 React 的核心库, react-dom.js 是提供与 DOM 相关的功能, Browser.js 的作用是将 JSX 语法转为 JavaScript 语法,这一步很消耗时间,实际上线的时候,应该将它放到服务器完成。

$ babel src --out-dir build

上面命令可以将 src 子目录的 js 文件进行语法转换,转码后的文件全部放在 build 子目录。

二、ReactDOM.render()

ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。

ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('example')

上面代码将一个 h1 标题,插入 example 节点(查看 demo01 ),运行结果如下。

三、JSX 语法

上一节的代码, HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是 JSX 的语法 ,它允许 HTML 与 JavaScript 的混写(查看 Demo02 )。

var names = ['Alice', 'Emily', 'Kate']; ReactDOM.render( names.map(function (name) { return <div>Hello, {name}!</div> </div>, document.getElementById('example')

上面代码体现了 JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。上面代码的运行结果如下。

JSX 允许直接在模板插入 JavaScript 变量。如果这个变量是一个数组,则会展开这个数组的所有成员(查看 demo03 )。

var arr = [ <h1>Hello world!</h1>, <h2>React is awesome</h2>, ReactDOM.render( <div>{arr}</div>, document.getElementById('example')

上面代码的 arr 变量是一个数组,结果 JSX 会把它的所有成员,添加到模板,运行结果如下。

React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。React.createClass 方法就用于生成一个组件类(查看 demo04 )。

var HelloMessage = React.createClass({ render: function() { return <h1>Hello {this.props.name}</h1>; ReactDOM.render( <HelloMessage name="John" />, document.getElementById('example')

上面代码中,变量 HelloMessage 就是一个组件类。模板插入 <HelloMessage /> 时,会自动生成 HelloMessage 的一个实例(下文的"组件"都指组件类的实例)。所有组件类都必须有自己的 render 方法,用于输出组件。

注意,组件类的第一个字母必须大写,否则会报错,比如 HelloMessage 不能写成 helloMessage 。另外,组件类只能包含一个顶层标签,否则也会报错。

var HelloMessage = React.createClass({ render: function() { return <h1> Hello {this.props.name} </h1><p> some text

上面代码会报错,因为 HelloMessage 组件包含了两个顶层标签: h1 p

组件的用法与原生的 HTML 标签完全一致,可以任意加入属性,比如 <HelloMessage name="John"> ,就是 HelloMessage 组件加入一个 name 属性,值为 John 。组件的属性可以在组件类的 this.props 对象上获取,比如 name 属性就可以通过 this.props.name 读取。上面代码的运行结果如下。

添加组件属性,有一个地方需要注意,就是 class 属性需要写成 className for 属性需要写成 htmlFor ,这是因为 class for 是 JavaScript 的保留字。

五、this.props.children

this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点(查看 demo05 )。

var NotesList = React.createClass({ render: function() { return ( React.Children.map(this.props.children, function (child) { return <li>{child}</li>; &lt/ol> ReactDOM.render( <NotesList> <span>hello</span> <span>world</span> </NotesList>, document.body

上面代码的 NoteList 组件有两个 span 子节点,它们都可以通过 this.props.children 读取,运行结果如下。

这里需要注意, this.props.children 的值有三种可能:如果当前组件没有子节点,它就是 undefined ;如果有一个子节点,数据类型是 object ;如果有多个子节点,数据类型就是 array 。所以,处理 this.props.children 的时候要小心。

React 提供一个工具方法 React.Children 来处理 this.props.children 。我们可以用 React.Children.map 来遍历子节点,而不用担心 this.props.children 的数据类型是 undefined 还是 object 。更多的 React.Children 的方法,请参考 官方文档

六、PropTypes

组件的属性可以接受任意值,字符串、对象、函数等等都可以。有时,我们需要一种机制,验证别人使用组件时,提供的参数是否符合要求。

组件类的 PropTypes 属性,就是用来验证组件实例的属性是否符合要求(查看 demo06 )。

var MyTitle = React.createClass({ propTypes: { title: React.PropTypes.string.isRequired, render: function() { return <h1> {this.props.title} </h1>;

上面的 Mytitle 组件有一个 title 属性。 PropTypes 告诉 React,这个 title 属性是必须的,而且它的值必须是字符串。现在,我们设置 title 属性的值是一个数值。

var data = 123; ReactDOM.render( <MyTitle title={data} />, document.body

这样一来, title 属性就通不过验证了。控制台会显示一行错误信息。

Warning: Failed propType: Invalid prop `title` of type `number` supplied to `MyTitle`, expected `string`.

更多的 PropTypes 设置,可以查看 官方文档

此外, getDefaultProps 方法可以用来设置组件属性的默认值。

var MyTitle = React.createClass({ getDefaultProps : function () { return { title : 'Hello World' render: function() { return <h1> {this.props.title} </h1>; ReactDOM.render( <MyTitle />, document.body

上面代码会输出"Hello World"。

七、获取真实的DOM节点

组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。

但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 ref 属性(查看 demo07 )。

var MyComponent = React.createClass({ handleClick: function() { this.refs.myTextInput.focus(); render: function() { return ( <input type="text" ref="myTextInput" /> <input type="button" value="Focus the text input" onClick={this.handleClick} /> ReactDOM.render( <MyComponent />, document.getElementById('example')

上面代码中,组件 MyComponent 的子节点有一个文本输入框,用于获取用户的输入。这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。为了做到这一点,文本输入框必须有一个 ref 属性,然后 this.refs.[refName] 就会返回这个真实的 DOM 节点。

需要注意的是,由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取 this.refs.[refName] 属性。

React 组件支持很多事件,除了 Click 事件以外,还有 KeyDown Copy Scroll 等,完整的事件清单请查看 官方文档

八、this.state

组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI (查看 demo08 )。

var LikeButton = React.createClass({ getInitialState: function() { return {liked: false}; handleClick: function(event) { this.setState({liked: !this.state.liked}); render: function() { var text = this.state.liked ? 'like' : 'haven\'t liked'; return ( <p onClick={this.handleClick}> You {text} this. Click to toggle. ReactDOM.render( <LikeButton />, document.getElementById('example')

上面代码是一个 LikeButton 组件,它的 getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化, this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。

由于 this.props this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是, this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。

用户在表单填入的内容,属于用户跟组件的互动,所以不能用 this.props 读取(查看 demo9 )。

var Input = React.createClass({ getInitialState: function() { return {value: 'Hello!'}; handleChange: function(event) { this.setState({value: event.target.value}); render: function () { var value = this.state.value; return ( <input type="text" value={value} onChange={this.handleChange} /> <p>{value}</p> ReactDOM.render(<Input/>, document.body);

上面代码中,文本输入框的值,不能用 this.props.value 读取,而要定义一个 onChange 事件的回调函数,通过 event.target.value 读取用户输入的值。 textarea 元素、 select 元素、 radio 元素都属于这种情况,更多介绍请参考 官方文档

十、组件的生命周期

组件的 生命周期 分成三个状态:

  • Mounting:已插入真实 DOM
  • Updating:正在被重新渲染
  • Unmounting:已移出真实 DOM
  • React 为每个状态都提供了两种处理函数, will 函数在进入状态之前调用, did 函数在进入状态之后调用,三种状态共计五种处理函数。

  • componentWillMount()
  • componentDidMount()
  • componentWillUpdate(object nextProps, object nextState)
  • componentDidUpdate(object prevProps, object prevState)
  • componentWillUnmount()
  • 此外,React 还提供两种特殊状态的处理函数。

  • componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
  • shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用
  • 这些方法的详细说明,可以参考 官方文档 。下面是一个例子(查看 demo10 )。

    var Hello = React.createClass({ getInitialState: function () { return { opacity: 1.0 componentDidMount: function () { this.timer = setInterval(function () { var opacity = this.state.opacity; opacity -= .05; if (opacity < 0.1) { opacity = 1.0; this.setState({ opacity: opacity }.bind(this), 100); render: function () { return ( <div style={{opacity: this.state.opacity}}> Hello {this.props.name} ReactDOM.render( <Hello name="world"/>, document.body

    上面代码在 hello 组件加载以后,通过 componentDidMount 方法设置一个定时器,每隔100毫秒,就重新设置组件的透明度,从而引发重新渲染。

    另外,组件的 style 属性的设置方式也值得注意,不能写成

    style="opacity:{this.state.opacity};" style={{opacity: this.state.opacity}}

    这是因为 React 组件样式 是一个对象,所以第一重大括号表示这是 JavaScript 语法,第二重大括号表示样式对象。

    十一、Ajax

    组件的数据来源,通常是通过 Ajax 请求从服务器获取,可以使用 componentDidMount 方法设置 Ajax 请求,等到请求成功,再用 this.setState 方法重新渲染 UI (查看 demo11 )。

    var UserGist = React.createClass({ getInitialState: function() { return { username: '', lastGistUrl: '' componentDidMount: function() { $.get(this.props.source, function(result) { var lastGist = result[0]; if (this.isMounted()) { this.setState({ username: lastGist.owner.login, lastGistUrl: lastGist.html_url }.bind(this)); render: function() { return ( {this.state.username}'s last gist is <a href={this.state.lastGistUrl}>here</a>. ReactDOM.render( <UserGist source="https://api.github.com/users/octocat/gists" />, document.body

    上面代码使用 jQuery 完成 Ajax 请求,这是为了便于说明。React 本身没有任何依赖,完全可以不用jQuery,而使用其他库。

    我们甚至可以把一个Promise对象传入组件,请看 Demo12

    ReactDOM.render( <RepoList promise={$.getJSON('https://api.github.com/search/repositories?q=javascript&sort=stars')} document.body

    上面代码从Github的API抓取数据,然后将Promise对象作为属性,传给 RepoList 组件。

    如果Promise对象正在抓取数据(pending状态),组件显示"正在加载";如果Promise对象报错(rejected状态),组件显示报错信息;如果Promise对象抓取数据成功(fulfilled状态),组件显示获取的数据。

    var RepoList = React.createClass({ getInitialState: function() { return { loading: true, error: null, data: null}; componentDidMount() { this.props.promise.then( value => this.setState({loading: false, data: value}), error => this.setState({loading: false, error: error})); render: function() { if (this.state.loading) { return <span>Loading...</span>; else if (this.state.error !== null) { return <span>Error: {this.state.error.message}</span>; else { var repos = this.state.data.items; var repoList = repos.map(function (repo) { return ( <a href={repo.html_url}>{repo.name}</a> ({repo.stargazers_count} stars) <br/> {repo.description} return ( <h1>Most Popular JavaScript Projects in Github</h1> <ol>{repoList}</ol> </main>

    十二、参考链接

  • React's official site
  • React's official examples
  • React (Virtual) DOM Terminology , by Sebastian Markbåge
  • The React Quick Start Guide , by Jack Callister
  • Learning React.js: Getting Started and Concepts , by Ken Wheeler
  • Getting started with React , by Ryan Clark
  • React JS Tutorial and Guide to the Gotchas , by Justin Deal
  • React Primer , by Binary Muse
  • jQuery versus React.js thinking , by zigomir
  • 由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。

    props,在这里很常见的用法是传参,显然形参你改了也灭用
    而state这个属性就要好好把玩了,也说了,交互中很常见的状态

    Facebook 在 React.js Conf 2015 大会上推出了基于 JavaScript 的开源框架 React Native,结合了 Web 应用和 Native 应用的优势,可以使用 JavaScript 来开发 iOS 和 Android 原生应用。

    下面是对 React Native 官方文档的完整中文翻译教程:http://wiki.jikexueyuan.com/project/react-native/

    现在真心不想用框架了, knockout, backbone, angular以及这个.
    每次为了适应一个新框架, 需要学习很多额外的语法, 而且等到其他人来维护的时候, 却完全维护不动...
    我决定以后顶多用个jQuery, 差不多大家都能看明白;
    如果是移动端直接就原生写吧, 实际上也没多少代码量.

    现在真心不想用框架了, knockout, backbone, angular以及这个.
    每次为了适应一个新框架, 需要学习很多额外的语法, 而且等到其他人来维护的时候, 却完全维护不动...
    我决定以后顶多用个jQuery, 差不多大家都能看明白;
    如果是移动端直接就原生写吧, 实际上也没多少代码量.

    那你最好去当个教师。不要做前端了

    文章开头讲到参见《也许,DOM 不是答案》,和React没太大关系。《也许,DOM 不是答案》是篇值得深思的文章,那篇文章给出的答案是新的页面渲染方式,倾向仍然是web端。
    而React只是稍微新一点的编写方式。Native解决的是减少工作量,统一的代码,性能能好吗?已经有太多项目做过这样的尝试了,还说什么“如果能够实现,整个互联网行业都会被颠覆”,别逗了。
    React不会解决那篇文章说的问题,也挨不上关系。

    var HelloMessage = React.createClass({
    render: function() {
    return <h1>Hello {this.props.name}</h1>;

    React.render(
    <HelloMessage name="John" />,
    document.getElementById('example')
    阮老师,为什么插入之后的html结构,会分别有两个span标签包裹着Hello和{this.props.name}呢?

    现在真心不想用框架了, knockout, backbone, angular以及这个.
    每次为了适应一个新框架, 需要学习很多额外的语法, 而且等到其他人来维护的时候, 却完全维护不动...
    我决定以后顶多用个jQuery, 差不多大家都能看明白;
    如果是移动端直接就原生写吧, 实际上也没多少代码量.

    所以充其量你永远只是一个小码农。不愿接受新事物,墨守陈规。

    文中说只要调用 setState 方法,就会自己调用 render 方法,重新渲染组件,
    八、表单 这节中,我看到 p 标签中使用 {value},input 标签中也是使用value={value},
    但是改变 input 中内容,只有 p 中内容跟着改变了,input 的 value 属性值没有跟着改变,
    那 render 方法到底是怎么执行的呢?没有重新渲染 input 吗?

    文中说只要调用 setState 方法,就会自己调用 render 方法,重新渲染组件,
    八、表单 这节中,我看到 p 标签中使用 {value},input 标签中也是使用value={value},
    但是改变 input 中内容,只有 p 中内容跟着改变了,input 的 value 属性值没有跟着改变,
    那 render 方法到底是怎么执行的呢?没有重新渲染 input 吗?

    render 的时候重新生成了 Virtual DOM,但重新渲染UI时,React 只会对 Virtual DOM 中发生改变了的部分进行重新渲染。render 后 Virtual DOM 中 input 的 value 属性值其实发生了变化,但和真实 DOM 中 input 的 .value 想用,故没有渲染到UI中。
    PS. 你可以通过在 input 上加上 ref="myTextInput",并在 handleChange 里加入 console.log(this.refs["myTextInput"].props); 来打印 Virtual DOM 的属性值来发现其中奥妙。

    看你Demo11中说ajax请求的数据要通过setState来触发渲染,事实上ajax请求之前就会调用初始的state默认渲染一次,例子中初始state比较简单:
    getInitialState: function() {
    return {
    username: '',
    lastGistUrl: ''
    那问题是我请求的数据结构很复杂,那初始state必须得完全照搬复杂的数据结构?要不然第一次渲染时就会报错!

    现在真心不想用框架了, knockout, backbone, angular以及这个.
    每次为了适应一个新框架, 需要学习很多额外的语法, 而且等到其他人来维护的时候, 却完全维护不动...
    我决定以后顶多用个jQuery, 差不多大家都能看明白;
    如果是移动端直接就原生写吧, 实际上也没多少代码量.

    你说的这段话很符合你的用户名

    阮老师第一个例程里面的<script type="text/babel"> 貌似写错了
    <script type="text/jsx">
    // ** Our code goes here! **
    </script>

    我个人的感觉,JSX是需要React解析的,这种语法糖也会改变开发JavaScript的开发方式,时间久了会导致原生JavaScript不熟了,因为好多问题你要前端非常熟悉JavaScript,否则就导致漫天大海的在网上找解决方案。

    我个人觉得,类似React的这种东东不要改变JavaScript写代码方式,可以在用JavaScript编写面向对象的组件上解决组件开发中单点的处理,而不是弄一套体系改变前端开发人员的开发方式。

    现在真心不想用框架了, knockout, backbone, angular以及这个.
    每次为了适应一个新框架, 需要学习很多额外的语法, 而且等到其他人来维护的时候, 却完全维护不动...
    我决定以后顶多用个jQuery, 差不多大家都能看明白;
    如果是移动端直接就原生写吧, 实际上也没多少代码量.

    - - 那 Facebook 为啥要用 , 不是你想的那样的 .

    没有 MVC 框架 , 你写 bootstrap semantic UI 试试

    阮老师第一个例程里面的<script type="text/babel"> 貌似写错了
    <script type="text/jsx">
    // ** Our code goes here! **
    </script>

    不太明白,应该是"text/jsx"还是"text/babel"

    留个链接, 我是 React 中文社区维护者之一(跟 Facebook 无关..).
    社区交流的渠道可以在 http://nav.react-china.org/ 查看.
    如果大家有兴趣追最新的消息, 交流跟分享 React, 可以细看一下.

    Diff算法解释是否已收入React中文社区http://www.laolifactory.com/index.php/2015/10/19/reacts-diff-algorithm-chinese/ Each child in an array or iterator should have a unique “key” prop

    解决办法只要在循环的每个子项添加一个key就行了,代码如下:

    var names = ['Alice', 'Emily', 'Kate'];
    ReactDOM.render(
    names.map(function (name, key) {
    return Hello, {name}!
    document.getElementById('example')

    http://f00sun.com/

    四:添加组件属性,有一个地方需要注意,就是 class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。

    试了一下,属性class和for都可以在页面上输出,代码(html忘记转义了,再发一次):
    var HelloMessage = React.createClass({
    render: function() {
    return <div>
    <p>HelloMessage组件属性</p>
    <p>name: {this.props.name}</p>
    <p>date: {this.props.date}</p>
    <p>class: {this.props.class}</p>
    <p>className: {this.props.className}</p>
    <p>for: {this.props.for}</p>
    <p>htmlFor: {this.props.htmlFor}</p>
    </div>;
    ReactDOM.render(
    <HelloMessage name="张三" date="2015-10-30" class="icon iocn_home" for="AAA" className="BBB" htmlFor="CCC"/>,
    document.getElementById('example')

    谢谢阮老师~

    demo2和demo3里迭代数组会报警告: Warning: Each child in an array or iterator should have a unique "key" prop. Check the top-level render call using

    另外demo9也会报警告不要直接插入document.body.

    谢谢阮老师~

    demo2和demo3里迭代数组会报警告: Warning: Each child in an array or iterator should have a unique "key" prop. Check the top-level render call using

    另外demo9也会报警告不要直接插入document.body.

    你可以参考这篇文章: 虚拟DOM Diff算法解析

    现在真心不想用框架了, knockout, backbone, angular以及这个.
    每次为了适应一个新框架, 需要学习很多额外的语法, 而且等到其他人来维护的时候, 却完全维护不动...
    我决定以后顶多用个jQuery, 差不多大家都能看明白;
    如果是移动端直接就原生写吧, 实际上也没多少代码量.

    先攒一下阮一峰老师,Angularjs现在正在用,完成俩一下项目,感觉很顺,代码量少backbone和angular我认为不能比,angular的模板载入绝了,还有路由都不错感觉比react完整,适合面向对象抽像不强人用,解耦等都不错,阮一峰老师这个文章入门真好,个人认为react面向对象抽像要强才能写的好

    React非常优秀,阮老师也一直非常优秀,非常好的一篇入门文章,阮老师一直出精华。
    React亮点是html作为了js组件,实现了dom diff和状态机的思想。
    React解决的一些问题,其实用一些简易优秀库,各取其核心,一样可以实现需求,而且开发成本也低,不会像React一样,各种查api,时间大部分都花在了看api上
    但个人认为,前端开发应该简而大方,不应该被一个react或angular局限在它们的生态圈中。一年前还有很多人在追逐angular,想着统一天下,现在又开始追逐react
    没有完美的框架存在。简单了,维护性才好

    真心赞一个,给了我们新手不少帮助,

    另外在重复一个问题,我也遇到了demo2和demo3里迭代数组会报警告: Warning: Each child in an array or iterator should have a unique "key" prop. Check the top-level render call using

    这个该怎么解决?

    引用邬畏畏的发言:

    我个人的感觉,JSX是需要React解析的,这种语法糖也会改变开发JavaScript的开发方式,时间久了会导致原生JavaScript不熟了,因为好多问题你要前端非常熟悉JavaScript,否则就导致漫天大海的在网上找解决方案。

    我个人觉得,类似React的这种东东不要改变JavaScript写代码方式,可以在用JavaScript编写面向对象的组件上解决组件开发中单点的处理,而不是弄一套体系改变前端开发人员的开发方式。

    React是可以不用JSX的,可以直接写js

    jsx:Hello {this.props.name}
    js:React.createElement("div", null, "Hello ", this.props.name);

    主要是jsx的类html语法比起原生js容易构建用户界面,嵌套层次一多自然会去用jsx了,只是做一层预编译

    您好,我在执行demo2/inde.html时,报错如下Warning: Each child in an array or iterator should have a unique "key" prop. Check the top-level render call using <div>. See https://fb.me/react-warning-keys for more information.
    虽然对页面显示没有影响,但是我想知道为何会报这样的错误,以及如何解决?
    我有试着百度结果,但是最终还是没有解决,希望您能够抽空解答一下,谢谢……

    引用李黎的发言:

    您好,我在执行demo2/inde.html时,报错如下Warning: Each child in an array or iterator should have a unique "key" prop. Check the top-level render call using <div>. See https://fb.me/react-warning-keys for more information.
    虽然对页面显示没有影响,但是我想知道为何会报这样的错误,以及如何解决?
    我有试着百度结果,但是最终还是没有解决,希望您能够抽空解答一下,谢谢……

    由于React注重UI效率,使用Virtual DOM Diff来提高效率,最小化Html DOM渲染开销,所以遇到DOM nodelist时期望每个node有个key来做引用标识, 这仅仅是一个Warning,一般不会对你的App功能造成影响,但是应该注意此类问题,大规模View中可能会引发性能问题。

    解决此问题的方法就是给你的Virtual DOM Nodelist中每个Node加唯一的key标识。

    {List.map(function(item){
    return (<li key={"Item-"+item.id}>{item.name}</li>);

    因为ReactJS的大名一直如雷贯耳,所以便花了些时间了解一下。原本以为只是简单的不同于JQuery的封装,但实际上却是完全打破了以前HTML开发的模式。
    看到上面一大串的拍马评论,和对那位名为“初学者”的留言用户的抨击,忍不住写下看法。
    从使用HTML属性到HTML和CSS分离,再到JavaScript处理逻辑,用了不短的时间。现在很少看到杂糅着各种语言的页面代码。
    所以,最初看到ReactJs代码的时候,简直不敢相信眼睛,这么多年分离的结果,又活生生地杂糅到了一起。
    歪果仁的创新能力的确强,前端这点东西折腾出了很多新的花样。但是FB的东西,实在是不敢说都是能改变世界的东西。FB为了让PHP更快用HHVM,脱离标准PHP。是的,他们的确是可以做到,很牛逼。但是这样真的好吗?最新的PHP7已经面世,打脸一般地证明了标准PHP同样可以很快。
    ReactJS混合了JS代码和HTML代码,其实它只想做一件事情,那就是组件化前端。但是组件化前端真的有必要用这么极端和不优雅的实现方式么?JS的地位如今已经被哄抬到了一个它设计之初都没想到的位置。以至于为了坐上王位,JS必须用它不算坚固的权杖,支撑起自己。JS的语法结构根本很难以这样无限制的拓展和包容一切。
    ReactJS概念的确是新颖,但是这不代表它就一定比分离代码和显示的模版优秀。组件化就代表着可复用?组件化就意味着可工程化。分离的模版就没法复用,没法工程化?
    最大的一套说辞往往就是“未来的页面会日趋复杂”,真相真的是这样吗?不得不承认,现今的互联网页面的确是比二十年前的页面复杂,但是页面再复杂,也终究是有极限的。简单的设计风格已经逐渐成为设计潮流,复杂的页面难道没有又逐渐变简单的趋势吗?除了淘宝这类电商的页面复杂无比外,还有多少网站是需要极其复杂的动态前端。
    越是简单的页面越是能让用户易于理解和提高更好体验不是吗?至于什么丰富的交互,革命性体验,ReactJS和普通前端架构又有什么区别。
    组件化可维护性很强,的确,从名称上看起来就有很强维护性。现在后端的代码也是所谓的组件化,甚至各种设计模式的应用,放到现实中的项目,真的能说“可维护性”很强吗?
    传统前端所见即所得,我思即我需,应该更为贴近人类思想,这不正是编程语言所一直努力的方向么。
    未来前端肯定会有更好的方向和发展,但绝对不会是ReactJS。

    问一句,如果我有一个想重复使用的组件,如果组件定义的代码放在一个单独的js文件里。
    多个页面的多个地方要使用这个组件,有什么办法吗?
    刚开始学习这个东西,也只是研究性质的,貌似组件的定义和组件的渲染一定要写作一起,不能独立开来的。
    var SingleArticle = React.createClass({
    render: function() {
    return (
    SomeArticle
    ReactDOM.render(React.createElement(SingleArticle, null),
    document.body);

    还有,在式样定义上也觉得蛮奇葩的,JSX不走标准化路线,可能学了之后,没有其他使用的地方。
    React Native还是算了吧,开发Native的程序的成本现在也很低了。

    大神您好!本人初学前端;想请教下,demo10的bind(this)的用法,如果我把这个去掉,系统就会报错:
    Uncaught TypeError: Cannot read property 'opacity' of undefined
    想问下,这里为什么是这样写的呢?
    期待回复,谢谢

    this.props.promise.then(
    value => this.setState({loading: false, data: value}),
    error => this.setState({loading: false, error: error}));

    这个没看懂,this.props.promise.then是什么意思?

    this.props.promise.then(
    value => this.setState({loading: false, data: value}),
    error => this.setState({loading: false, error: error}));

    这个没看懂,this.props.promise.then是什么意思?

    .then()是jquery的方法,参数(success(),error())
    =>是es6语法,我理解为
    componentDidMount() {
    this.props.promise.then(
    function(value){this.setState({loading: false, data: value})}.bind(this),
    function(error){this.setState({loading: false, error: error})}.bind(this)

    作为模版,得到类似dw 这类可视化Html ide的支持的是必须的。。

    改进建议:使用html文件作为组件,小型组件可以使用ajax读取载入,这样组件可以方便dw的设计。。大型组件可以使用ajax载入,也可以iframe方式载入。。

    2.2.组件的html与js的集成是以js为基础的

    这导致了界面可视化设计极差。。应该以html dom为基础,在html的基础上内嵌js。。Js本身就是代码,可视化要求相对较低。。Dom 标签使用常用的class 增加一个特点的oocss class来表明一个组件的类型,以及复合组件,或者可增加一个扩展属性。。

    2.3.组件的属性以js为主

    这带来查看属性值的调试的问题,如果可以在html标签上扩展属性,就方便调试,毕竟浏览器查看工具可以一目了然的查看属性的值

    请问如果定义 var MyButton = React.createClass({...})放在单独文件里比如 abc.js
    html页面引用 <script type="text/babel" src="js/abc.js"></script>

    页面来定义在哪里渲染(其实为了重用),页面调用:

    <script type="text/babel">
    ReactDOM.render(
    <div><MyButton text="sure2"/></div>,
    document.getElementById('content')
    </script>

    为什么不行?
    Uncaught ReferenceError: MyButton is not defined

    Web的问题是否能够依靠"组件化"来解决是需要讨论的?但现在出现的现象,是我们过于关注技术本身,而忽略了Web自身的特性。如此众多的组件库和框架都试图证明自己是解决Web的不二法则,有注重服务器端解决方案的,例如
    * Tag library - Struts Tag
    * Template Engineer - Velocity, Freemaker
    * Components: Awt/Swing, JSF

    有关注客户端的解决方案的,例如
    * Flash, Applet
    * java-script library: YUI, Dojo
    * java-script framework: Angular, EmberJs, Rect.js

    那么什么是Web的实质呢?它原本只是用来展现数据的载体,至于什么方式或者方法其实是无所谓,你用Struts Tag也好用Dojo也好,都只是为"展示"这个动作服务的。过分的关注工具的使用,而忽略了技术之外的东西(比如Dom, CSS, javascript语言这些本身的特点)就本末倒置了。

    我还是有疑问,componentDidMount已经是渲染完成了,这就证明组建已经肯定是处于mounting状态的。$.get(url,function)这里的function是成功后的回调,也就是说,数据已经返回了。
    1、组件状态是mounting状态。
    2、数据已经返回。
    为什么还要判断isMounted()?

    引用业界大牛的发言:

    由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。

    props,在这里很常见的用法是传参,显然形参你改了也灭用
    而state这个属性就要好好把玩了,也说了,交互中很常见的状态

    怎么感觉你是 => 张鑫旭大师呢

    demo13 npm install 安装后运行node server.js还是报错,应该是jsx编译报错
    报错信息是
    E:\www\myTest\react-demos-master\demo13\src\server.js:20

    SyntaxError: Unexpected token <
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Function.Module.runMain (module.js:441:10)
    at startup (node.js:139:18)
    at node.js:968:3

    烦问这是什么原因?试过直接安装babel-core 和 babel-cli也不行

    React是facebook的项目,然而他们的老大,马克扎尔伯格不是说过自己投资HTML5是极大的失败吗?那我很好奇他对于HTML5相关的项目或者技术的支持力度能有多大,或者说有多久?
    一个框架,不是要看它一时的风光,而是未来的可维护性。jQuery为何能够生存十年还屹立不倒?这离不开数万个程序员的你一字我一句的代码维护。
    如果真的要制作MVC框架,其实Angular就是个很好的选择了吧,至少人家在1.X版本风靡的前提下,胆敢大刀阔斧的推出2.X版本,这本身就说明了这个团队的精益求精。
    此外,项目也必须考虑到后续的维护呀,如果现在用的是昙花一现的框架,那么接手的人遇到了问题,想在网上找个解决方案都不太容易,总不能让他们重新制作一个网站吧?

    引用瀚海的发言:

    React是facebook的项目,然而他们的老大,马克扎尔伯格不是说过自己投资HTML5是极大的失败吗?那我很好奇他对于HTML5相关的项目或者技术的支持力度能有多大,或者说有多久?
    如果真的要制作MVC框架,其实Angular就是个很好的选择了吧,至少人家在1.X版本风靡的前提下,胆敢大刀阔斧的推出2.X版本,这本身就说明了这个团队的精益求精。

    正因为追求极致,才推进了前端行业的蓬勃发展。丰富的交互,革命性体验,ReactJS确实比其他普通前端架构更好,特别是移动端,甩Angular几条街。虚拟dom这一概念提高了web性能,部分其它类似的框架都是直接操作DOM,这点不得不服。单看fps,实际测试react在51-60fps, h5在33-55fps。
    还有native方面,追求App和wap的统一,react提供了目前最好的方式。
    当然实际开发项目里,不只有react,还有和他相关的好多,比如redux,router,为了追求极致,你还可以再上immutable.js。react实现了完全的前后端分离,国内目前也有好多再用了。
    颠覆了传统的前端行业,目前在学习,着实惊叹!!!

    this.props.promise.then(
    value => this.setState({loading: false, data: value}),
    error => this.setState({loading: false, error: error}));

    请问这段代码是什么意思呢?有什么地方可以深入研究

    这里推荐一个关于react的比较好的网页: http://survivejs.com。

    里边主要分两大篇, 一篇是说如何成为react高手, 另一篇是如何使用webpack来进行工程化管理的, 都比较经典。

    里边提供了最终源码, 不过建议从头开始,一步步读下去, 边读边写, 边看效果。 对react, webpack的认识和使用还是蛮有帮助的。

    虽然现在还不是很熟悉, 但能上手一点点简单的东西, 大家有兴趣可以看我的github demo :
    https://github.com/walkerqiao/react-redux-router-demo.git

    欢迎大家一起探讨学习。

    引用业界大牛的发言:

    由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。

    props,在这里很常见的用法是传参,显然形参你改了也灭用
    而state这个属性就要好好把玩了,也说了,交互中很常见的状态

    看了阮老师教程就是能静下心来看入,我也发现这里this.props 和 this.state

    个人认为最大区别是

    this.props 是组件被引用时在组件自身内部 用 this.props 接收 当前自身的所有属性value

    this.state 是组件自身内部操作

    不知道对不对,有知道朋友指点一下

    添加组件属性,有一个地方需要注意,就是 class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。

    class 和 for应该是ES6(ECMAScript 6)的保留关键字比较好点

    “添加组件属性,有一个地方需要注意,就是 class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。

    这个地方还是不明白。我这样写☞

    通过☞{this.props.class} {this.props.for}依旧可以取到。

    “class 和 for 是 JavaScript 的保留字”不影响我取 this.props 对象的属性啊,对不?

    render 的时候重新生成了 Virtual DOM,但重新渲染UI时,React 只会对 Virtual DOM 中发生改变了的部分进行重新渲染。render 后 Virtual DOM 中 input 的 value 属性值其实发生了变化,但和真实 DOM 中 input 的 .value 想用,故没有渲染到UI中。
    PS. 你可以通过在 input 上加上 ref="myTextInput",并在 handleChange 里加入 console.log(this.refs["myTextInput"].props); 来打印 Virtual DOM 的属性值来发现其中奥妙。

    我按照react官网的例子来学习,想用babel在本地将src/example.js转译生成到lib/example.js,从而去掉这个在线转译的,但是遇到以下问题:
    因为example.js中有使用jquery 的ajax方法$.ajax(),jQuery是在html页面头部引入的,使用babel转译之后运行,浏览器报错 $.ajax()is not a function...
    请问在利用babel本地转译的时候如何将react和jquery同时使用

    React 其實就是處理UI層 (view層)。 透過React 可輕易自行創造出類似 jqueryUI 的庫 (要配合自己的css), 從而在日後加速建立網頁和維護(由其是它的標籤化組件和輸入參數部份)。
    防止采集又多了一層保護!?

    就如站長所說, 如果數據是單一化, 實在沒必要使用React,反而令項目更複雜。

    框架何其多,什至自己用JS 打出自己的一套東西都行,自己覺得那個順手就好了。

    歪果仁肆意民科,果仁溜须拍马。我不是说react,我是说react,angular,都是垃圾。

    为什么?因为所有实际参数少于需要参数的构造,无论它叫什么名字,都是函数的阉割,是不完备的。函数之所以不能让你爽,原因很简单,任何事物如果不受其他事物干扰,它基本上可正交定义,可稳定描述。如果被其他事物干扰,它就是不可正交定义,不可稳定描述的。只要事物不可稳定描述,这个描述是不完备的,基于这个描述的任何推论(也就是对它的任何调用)都是脆弱的,不完备的。

    你所企图得到的,只是以需求的最小正交全集自动推理整个系统实现的工具,根据哥德尔定理,完备的东西不能自洽,自洽的东西不会完备,所以实际上你所企图的是不可能得到的东西。

    不要小看了if和for这两个结构,当代码的执行路径依赖于运行时数据时,它就是下一阶逻辑,当前阶逻辑不可能知道下一阶逻辑,否则当前阶无输出时不需要执行,这是因果关系的最终局限。这种需要向前看的构造是不可以通过函数这种自顶向下的evaler来做动态规划的。

    上面那个人说的对,你们这些整天对歪果仁对函数阉割出新花样的套路捧臭脚,然后自鸣得意的人,真是作死作孽。

    handleChange: function(event) {
    this.setState({value: event.target.value});
    console.log(this.refs.myTextInput.value);
    console.log(this.state.value);
    render: function () {
    var value = this.state.value;
    return (

    {value}


    ReactDOM.render(, document.getElementById('example'));

    一下下按删除键,打印的是:
    Hello
    Hello!

    Hello

    为什么呀?

    我还是有疑问,componentDidMount已经是渲染完成了,这就证明组建已经肯定是处于mounting状态的。$.get(url,function)这里的function是成功后的回调,也就是说,数据已经返回了。
    1、组件状态是mounting状态。
    2、数据已经返回。
    为什么还要判断isMounted()?

    现在真心不想用框架了, knockout, backbone, angular以及这个.
    每次为了适应一个新框架, 需要学习很多额外的语法, 而且等到其他人来维护的时候, 却完全维护不动...
    我决定以后顶多用个jQuery, 差不多大家都能看明白;
    如果是移动端直接就原生写吧, 实际上也没多少代码量.

    如果你用框架写过复杂的交互项目,我想你应该不会这么说了吧

    this.setState({
    username: lastGist.owner.login, //octocat
    lastGistUrl: lastGist.owner.html_url, //https://github.com/octocat
    第十一个demo应该是 lastGist.owner.html_url

    @Cheny:

    一己之见,需求不同,见解不同,用法自然也就不同,各路诸侯分天下,终有见分晓的一天。但是,在代码技术的世界里,不等分晓现,后浪以上岸;科技无限,创造无限,不定的未来,也许会出现新的事物;

    目前,各取所需,自己认为好,团队认为好,公司认为好,即可。

    我这里也是demo13出错了,重新下载node_module也不行啊,,,报错信息是这样的:
    (index):1 GET https://fb.me/react-0.14.0.min.js net::ERR_CONNECTION_TIMED_OUT
    bundle.js:95 Uncaught TypeError: Cannot read property 'Component' of undefined
    at Object.2 (bundle.js:95)
    at s (bundle.js:1)
    at bundle.js:1
    at Object.1../app (bundle.js:14)
    at s (bundle.js:1)
    at e (bundle.js:1)
    at bundle.js:1