Fork me on GitHub

React入门

简介

  • React 是一个用于构建用户界面的 JAVASCRIPT 库
  • React主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)
  • React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源
  • React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它
  • React 拥有一个强大的组合模型,我们建议使用组合而不是继承以实现代码的重用
  • react有 函数式组件和类组件,现在的使用都以类组件为主,函数式组件不考虑
  • angualr霸道,用了之后原生定时器、jquery等都不能用,而react没有这个限制
  • react中对事件的大小写敏感,因为有一个编译过程
  • 相关有用网址
1
2
3
官网:https://facebook.github.io/react/
中文网站:http://www.css88.com/react/
中文论坛:http://react-china.org/

react特点

  1. 声明式设计 −React采用声明范式,可以轻松描述应用。
  2. 高效 −虚拟DOM,React通过对DOM的模拟,最大限度地减少与DOM的交互。React DOM 会将元素及其子元素与之前版本逐一对比, 并只对有必要更新的 DOM 进行更新, 以达到 DOM 所需的状态
  3. 灵活 −React可以与已知的库或框架很好地配合。
  4. JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
  5. 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
  6. 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单

react全家桶(技术栈)

如果一个技术你不知道,那说明你还用不上

  1. react:主体
  2. webpack、grunt、gulp自动化构建工具
  3. Flex:布局
  4. react-route:路由
  5. redux:view层
  6. Mocha:测试
  7. Istanbul:覆盖率

安装

网页使用

网页中用babel会页面加载会有编译过程,比较缓慢,babel也可以后台编译

1
2
3
4
5
6
7
8
9
<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>
<script type="text/babel">
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
</script>

引入了三个库: react.min.js 、react-dom.min.js 和 babel.min.js:

  1. react.min.js - React 的核心库
  2. react-dom.min.js - 提供与 DOM 相关的功能
  3. babel.min.js - Babel 可以将 ES6 代码转为 ES5 代码,这样我们就能在目前不支持 ES6 浏览器上执行 React 代码。Babel 内嵌了对 JSX 的支持。通过将 Babel 和 babel-sublime 包(package)一同使用可以让源码的语法渲染上升到一个全新的水平

使用 create-react-app 快速构建

1
2
3
4
$ cnpm install -g create-react-app
$ create-react-app my-app
$ cd my-app/
$ npm start

在浏览器中打开 http://localhost:3000/,查看结果

JSX

JSX是可选的,对于使用 React而言不需要

React 使用 JSX 来替代常规的 JavaScript,JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。

优点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化,需babel编译后才能运行,bower babel install,官网:http://babeljs.io/
  • 它是类型安全的,在编译过程中就能发现错误
  • 使用 JSX 编写模板更加简单快速

使用过程中的注意事项:

  1. 组件必须返回一个单独的根元素。render的内容必须有且仅有一个父元
  2. 网页中使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script src="js/react.js" charset="utf-8"/></script>
<script src="js/react-dom.js" charset="utf-8"/></script>
<script src="js/browser.js" charset="utf-8"/></script>
<script type="text/babel">
window.onload=function(){
var oDiv = document.getElementById("div1");
ReactDom.render(
<span>111</span>,//内容
oDiv//到哪
);
};
</script>
<body>
<div id="div1></div>
</body>
  1. 添加自定义属性需要使用 data- 前缀,因为jsx对html标签有识别,如果符合则不显示,而在自定义属性前面加data-可以保证显示显示
  2. 自定义组件可以单独文件存储
  3. 可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中;在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代
  4. React 推荐使用内联样式。我们可以使用 camelCase 语法来设置内联样式. React 会在指定元素数字后自动添加 px
  5. JSX 允许在模板中插入数组,数组会自动展开所有成员
  6. 注释:在标签内部的注释需要花括号;在标签外的的注释不能使用花括号
  7. 可以使用双引号来指定字符串字面量作为属性值
  8. class 在JSX中变为className,tabindex 变为 tabIndex
  9. React DOM 使用驼峰(camelCase)属性命名约定, 而不是HTML属性名称
1
2
3
4
5
ReactDOM.render(
/*注释 */
<h1>孙朝阳 {/*注释*/}</h1>,
document.getElementById('example')
);
  1. 如果你有一个单一模块(module) ,但却 导出(exports) 多个 React 组件时十分有用
1
2
3
4
5
6
7
8
9
10
11
import React from 'react';

const MyComponents = {
DatePicker: function DatePicker(props) {
return <div>Imagine a {props.color} datepicker here.</div>;
}
}

function BlueDatePicker() {
return <MyComponents.DatePicker color="blue" />;
}
  1. JSX 中的 Children:在 JSX 表达式中可以包含开放标签和闭合标签,标签中的内容会被传递一个特殊的 props(属性) : props.children

组件

  • 组件名称总是以大写字母开始
  • 组件有构造函数,构造函数的第一行应该是调用super函数,其参数为…args参数,在constructor方法中进行一些初始
  • 绑定事件的方式:onChange={this.函数名称.bind(this)}
  • 有狗那年,定时器中的this就不合适,在使用前通过_this=this保存一份,然后在定时中用_this代替
  • react处理了this,原生中如果要用this,最好也处理一下
  • react中阻止事件冒泡:ev.nativeEvent.stopImmediatePropergation
  • 父级属性传递给子级直接通过属性,子级属性传递给父级需要通过在父级绑定回调函数如cb(),在子级中通过this.props.cb(传递的参数)的方式把参数传递到父级
  • react中设置样式style需要通过双大括号}}来设置
  • 键(Keys) 帮助 React 标识哪个项被修改、添加或者移除了。数组中的每一个元素都应该有一个唯一不变的键(Keys)来标识。keys 只在数组的上下文中存在意义; keys 必须在它们的同辈之间唯一。然而它们并不需要全局唯一
  • 自定义组件的方式如下:
1
2
3
4
5
class 组件名称 extends React.Component{
render(){
retrun <span>我的年龄是:{this.props.age}</span>
}
}
1
2
3
4
5
6
//定义
class Comp extends React.Component{
render(){
return <span>111</span>;
}
}
  • 组件使用:类似于标签的使用
1
2
3
4
ReactDom.render(
<Comp age="18"/>,//内容,类名
document.body//到哪
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
window.onload=function(){ 
ReactDom.render(
<Comp/>,//内容,类名
document.body//到哪
);
};
~~~

# 状态state
* React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。
* React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
* this.setState({属性:'值'});
* state(状态) 更新可能是异步的。React 为了优化性能,有可能会将多个 setState() 调用合并为一次更新。因为 this.props 和 this.state 可能是异步更新的,你不能依赖他们的值计算下一个state(状态)。

# 属性props
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据

* 如果你没给 prop(属性) 传值,那么他默认为 true
* 控制表单的value,如果用props设置了默认值,由于props是死的,不能修改,修改为defaultValue即可
* 控制checkbox的默认值,修改为defalultChecked
* 属性扩展:如果你已经有一个 object 类型的 props,并且希望在 JSX 中传入,你可以使用扩展操作符 ... 传入整个 props 对象。以上两种方法等效:

function App1() {
return ;
}

function App2() {
const props = {firstName: ‘Ben’, lastName: ‘Hector’};
return <Greeting {…props} />;
}


# 组件生命周期
组件的生命周期可分成三个状态:
1. Mounting:已插入真实 DOM
2. Updating:正在被重新渲染
3. Unmounting:已移出真实 DOM

生命周期的方法有:
* componentWillMount 在渲染前调用,在客户端也在服务端
* componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异部操作阻塞UI)
* componentWillReceiveProps 在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用
* shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用
* componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用
* componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用
* componentWillUnmount在组件从 DOM 中移除的时候立刻被调用。==当使用异步加载数据时,在组件卸载前使用 componentWillUnmount 来取消未完成的请求==

# React Refs
* React 支持一种非常特殊的属性 Ref ,可以用来绑定到 render() 输出的任何组件上。
这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例
* 可以通过使用 this 来获取当前 React 组件,或使用 ref 来获取组件的引用
* ref 标示组件内的node,可以原生操作节点,在this.refs['ref名字']=原生
* React 支持给任何组件添加特殊属性。ref 属性接受回调函数,并且当组件 装载(mounted) 或者 卸载(unmounted) 之后,回调函数会立即执行
* 不能在函数式组件上使用 ref 属性,因为它们没有实例

# 使用 Chrome Timeline 分析组件性能
在 开发模式 中,你可以在支持相关功能的浏览器中使用性能工具来可视化组件 装载(mount) ,更新(update) 和 卸载(unmount) 的各个过程。在 Chrome 中具体操作如下: 
1. 通过添加 ?react_perf 查询字段加载你的应用(例如:http://localhost:3000/?react_perf)
2. 打开 Chrome DevTools Timeline 并点击 Record
3. 执行你想要分析的操作,不要超过20秒,否则 Chrome 可能会挂起
4. 停止记录
5. 在 User Timing 标签下,React事件将会分组列出

注意:上述数字是相对的,组件会在生产环境中会更快


# route
react-router + react-router-redux: 前者是业界标准,后者可以同步 route 信息到 state,这样你可以在 view 根据 route 信息调整展现,以及通过 action 来修改 route 。

本文标题:React入门

文章作者:行锋

发布时间:2018年10月26日 - 15:10

最后更新:2019年01月11日 - 00:01

原始链接:https://chetaofeng.github.io/2018/10/26/react-rn-2018-10-26-React入门/

许可协议: 署名-非商业性使用 转载请保留原文链接及作者

-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!