教学视频: http://www.php.cn/code/8217.htmlphp
React 教程: http://www.runoob.com/react/react-tutorial.htmlcss
本篇是菜鸡水准了解轮廓的难度等级,菜鸡啄米,叽叽喳喳html
先介绍仨工具:node
jspm: 是一个一个浏览器端包管理器;SystemJS加载js的模块,也有Babel编译js,JSX编译为js。jspm & SystemJS 教程react
Ref: https://blog.csdn.net/rical730/article/details/77206601webpack
1. 先安装:nodejs npmes6
2. 新建一个项目文件夹。web
mkdir React & cd React
3. 使用 create-react-app 快速构建 React 开发环境npm
sudo npm install -g create-react-app create-react-app my-app
4. 安装结束segmentfault
cd my-app npm start
5. 其余(option)
sudo npm install -g browser-sync Browsersync能让浏览器实时、快速响应您的文件更改(html、js、css、sass、less等)并自动刷新页面。
更重要的是 Browsersync能够同时在PC、平板、手机等设备下进项调试。
jspm install semantic-ui jspm install css
npm start 时,可见实际执行的是:npm run dev,而dev指得是另外一坨东西。
babel 帮助将es6编译为es5,然后执行。
1.声明式设计 −React采用声明范式,能够轻松描述应用。
2.高效 −React经过对DOM的模拟,最大限度地减小与DOM的交互。
3.灵活 −React能够与已知的库或框架很好地配合。
4.JSX − JSX 是 JavaScript 语法的扩展。React 开发不必定使用 JSX ,但咱们建议使用它。
5.组件 − 经过 React 构建组件,使得代码更加容易获得复用,可以很好的应用在大项目的开发中。
6.单向响应的数据流 − React 实现了单向响应的数据流,从而减小了重复代码,这也是它为何比传统数据绑定更简单。
Figure, 可见不适用jsx写的形式(下面),可读性不好。
React 使用 JSX 来替代常规的 JavaScript。
JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。
咱们不须要必定使用 JSX,但它有如下优势:
<!DOCTYPE html> <html>
<head> <meta charset="UTF-8" /> <title>菜鸟教程 React 实例</title> <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script> <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script> <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script> </head>
<body> <div id="example"></div> <script type="text/babel"> ReactDOM.render( <div> <h1>菜鸟教程</h1> <h2>欢迎学习 React</h2> <p data-myattribute = "somevalue">这是一个很不错的 JavaScript 库!</p> // p 元素添加了自定义属性 data-myattribute,须要使用 data- 前缀。 </div> // 第一个参数 , document.getElementById('example') // 第二个参数 ); </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello React!</title> <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script> <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script> <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script> </head> <body> <div id="example"></div> <script type="text/babel" src="helloworld_react.js"></script> // 另外存在单独文件更好 </body> </html>
// 在 JSX 中不能使用 if else 语句,但可使用 conditional (三元运算) 表达式来替代
ReactDOM.render( <div> <h1>{i == 1 ? 'True!' : 'False'}</h1> </div> , document.getElementById('example') );
React 推荐使用内联样式。
咱们可使用 camelCase 语法来设置内联样式.
React 会在指定元素数字后自动添加 px 。
如下实例演示了为 h1 元素添加 myStyle 内联样式:
var myStyle = { fontSize: 100, color: '#FF0000' }; ReactDOM.render( <h1 style = {myStyle}>菜鸟教程</h1>, document.getElementById('example') );
JSX 容许在模板中插入数组,数组会自动展开全部成员:
var arr = [ <h1>菜鸟教程</h1>, <h2>学的不只是技术,更是梦想!</h2>, ]; ReactDOM.render( <div>{arr}</div>, document.getElementById('example') );
组件类:开头大写React.createClass。
var HelloMessage = React.createClass({ // 组件类 HelloMessage render: function() { return <h1>Hello World!</h1>; } }); ReactDOM.render( <HelloMessage />, document.getElementById('example') );
传参数:向组件传递参数,可使用 this.props 对象,实例以下:
var HelloMessage = React.createClass({ render: function() { return <h1>Hello {this.props.name}</h1>; // name 属性经过 this.props.name 来获取。 } }); ReactDOM.render( <HelloMessage name="Runoob" />, document.getElementById('example') );
复合组件:建立多个组件来合成一个组件,把组件的不一样功能点进行分离。
var WebSite = React.createClass({ render: function() { return ( <div> <Name name={this.props.name} /> <Link site={this.props.site} /> </div> ); } });
var Name = React.createClass({ render: function() { return ( <h1>{this.props.name}</h1> ); } });
var Link = React.createClass({ render: function() { return ( <a href={this.props.site}> {this.props.site} </a> ); } });
ReactDOM.render( <WebSite name="菜鸟教程" site=" http://www.runoob.com" />, document.getElementById('example') );
React 把组件当作是一个状态机(State Machines)。经过
根本思想:React 里,只需更新组件的 state,而后根据新的 state 从新渲染用户界面(不要操做 DOM)。
例子:建立了 LikeButton 组件
1. getInitialState 方法用于定义初始状态,也就是一个对象,这个对象能够经过 this.state 属性读取。
2. 当用户点击组件,致使状态变化,this.setState 方法就修改状态值,
3. 每次修改之后,自动调用 this.render 方法,再次渲染组件。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>菜鸟教程 React 实例</title> <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script> <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script> <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script> </head>
<body> <div id="example"></div> <script type="text/babel"> var LikeButton = React.createClass({ getInitialState: function() { // 1 定义初始状态,也就是一个对象 return {liked: false}; }, handleClick: function(event) { this.setState({liked: !this.state.liked}); // 2 有点击事件,就改变状态:setState ----> render func }, render: function() { // 3 渲染组件, var text = this.state.liked ? '喜欢' : '不喜欢'; return ( <p onClick={this.handleClick}> 你<b>{text}</b>我。点我切换状态。 </p> ); } }); ReactDOM.render( <LikeButton />, document.getElementById('example') ); </script> </body>
</html>
props 是不可变的:子组件只能经过 props 来传递数据
state 能够根据与用户交互来改变:有些容器组件须要定义 state 来更新和修改数据。
var HelloMessage = React.createClass({ getDefaultProps: function() { return { name: 'Runoob' }; }, render: function() { return <h1>Hello {this.props.name}</h1>; } }); ReactDOM.render( <HelloMessage />, document.getElementById('example') );
分离的例子:(其实就是复合组件)
---------------------------------------------------------------
# 定义一个大组件
var WebSite = React.createClass({ getInitialState: function() { return { name: "菜鸟教程", site: "http://www.runoob.com" }; },
render: function() { // 1.0 在render函数中, 咱们设置 name 和 site 来获取父组件传递过来的数据 return ( <div> <Name name={this.state.name} /> // 在父组件中设置 state <Link site={this.state.site} /> </div> ); } });
---------------------------------------------------------------
# 定义大组件中的两个小组件
var Name = React.createClass({ render: function() { return ( <h1>{this.props.name}</h1> // 2.1 在子组件上使用 props 将其传递到子组件上 ); } });
var Link = React.createClass({ render: function() { return ( <a href={this.props.site}> {this.props.site} // 2.2 在子组件上使用 props 将其传递到子组件上 </a> ); } });
---------------------------------------------------------------
ReactDOM.render( <WebSite />, document.getElementById('example') );
Props 验证
实例建立一个 Mytitle 组件,属性 title 是必须的且是字符串,非字符串类型会自动转换为字符串 :
var title = "菜鸟教程"; // var title = 123; <---- 非字符串类型会自动转换为字符串 var MyTitle = React.createClass({ propTypes: { title: React.PropTypes.string.isRequired, }, render: function() { return <h1> {this.props.title} </h1>; } }); ReactDOM.render( <MyTitle title={title} />, document.getElementById('example') );
更多验证器说明以下:
React.createClass({ propTypes: { // 能够声明 prop 为指定的 JS 基本数据类型,默认状况,这些数据是可选的 optionalArray: React.PropTypes.array, optionalBool: React.PropTypes.bool, optionalFunc: React.PropTypes.func, optionalNumber: React.PropTypes.number, optionalObject: React.PropTypes.object, optionalString: React.PropTypes.string, // 能够被渲染的对象 numbers, strings, elements 或 array optionalNode: React.PropTypes.node, // React 元素 optionalElement: React.PropTypes.element, // 用 JS 的 instanceof 操做符声明 prop 为类的实例。 optionalMessage: React.PropTypes.instanceOf(Message), // 用 enum 来限制 prop 只接受指定的值。 optionalEnum: React.PropTypes.oneOf(['News', 'Photos']), // 能够是多个对象类型中的一个 optionalUnion: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.number, React.PropTypes.instanceOf(Message) ]), // 指定类型组成的数组 optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number), // 指定类型的属性构成的对象 optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number), // 特定 shape 参数的对象 optionalObjectWithShape: React.PropTypes.shape({ color: React.PropTypes.string, fontSize: React.PropTypes.number }), // 任意类型加上 `isRequired` 来使 prop 不可空。 requiredFunc: React.PropTypes.func.isRequired, // 不可空的任意类型 requiredAny: React.PropTypes.any.isRequired, // 自定义验证器。若是验证失败须要返回一个 Error 对象。不要直接使用 `console.warn` 或抛异常,由于这样 `oneOfType` 会失效。 customProp: function(props, propName, componentName) { if (!/matchme/.test(props[propName])) { return new Error('Validation failed!'); } } }, /* ... */ });
获取自定义组件的属性 - this.props.children
在render中,Child有了属性children,天然地,获取时就使用this.props.children。
this.props 对象的属性与组件的属性一一对应,可是有一个例外,就是 this.props.children 属性。
它表示组件的全部子节点:【全部子节点可能有三种不一样的状况】
var HelloWorld = React.createClass({ render:function(){ return ( <ul> { React.Children.map(this.props.children, function (value, key) { // 1. 获取子节点 return <li>{value}----{key}</li>; // 2. 以怎样的html形式展示 }) } </ul> ); } }); ReactDOM.render( <HelloWorld> <span>思考思考</span> <span>瞬间即逝</span> <span>阿达瓦得</span> </HelloWorld>, document.getElementById('root'));
Result:
思考思考—-0 瞬间即逝—-1 阿达瓦得—-2