React.js读书与总结:《react-tutorial》
最近接触的一个项目中使用了React为主要框架,虽然之前也多多少少学过一些React,但是还需要更深入的学习和更熟练的掌握,所以最近我打算好好的读上几本React的书,今天带来第一本书:《react-tutorial》的学习总结。
前言
技术在没有真正使用之前,没法评价哪一个好,没有最好的,只有最合适的。
一 Webpack 配置 React 开发环境
搭建一个现代的前端开发环境配套的工具有很多,比如 Grunt / Gulp / Webpack / Broccoli,
这些都是要解决前端工程化问题。
而ES6 编译工具 Babel,则内置了对 JSX 语法的支持。
(1)Webpack简介:
前端资源加载/打包工具,只需简单的配置就可提供前端工程化需要的各种功能,
如有需要还可被整合到其他如 Grunt / Gulp 的工作流
(2)webpack 的优势:
- 以 commonJS 的形式来书写脚本,对 AMD/CMD 的支持也很全面,方便旧项目进行代码迁移。
- 能被模块化的不仅仅是 JS 。
- 开发便捷,能替代部分 grunt/gulp 的工作,比如打包、压缩混淆、图片转base64等。
- 扩展性强,插件机制完善
(3)安装 Webpack:
npm install -g webpack
使用 webpack.config.js 配置文件
要编译 JSX,先安装对应的 loader: npm install babel-loader –save-dev
(4)webpack配置
webpack配置与使用可参考:
http://www.cnblogs.com/vajoy/p/4650467.html
http://www.jianshu.com/p/b95bbcfc590d
详细了解:
webpack官网: http://webpack.github.io/
文档地址: http://webpack.github.io/docs/
module下的loaders 是最关键的一块配置,它告知 webpack 每一种文件都需要使用什么加载器来处理。
webpack所有的loader列表和使用方法可参考:http://webpack.github.io/docs/list-of-loaders.html
二 JSX
(1)为什么要引入 JSX 这种语法?
传统的 MVC 是将模板放在其他地方,比如 script 标签或者模板文件,再在 JS 中通过某种手段引用模板。按这种思路,想想多少次我们面对四处分散的模板片段不知所措?纠结模板引擎,纠结模板存放位置,纠结如何引用模板。
React 认为组件才是王道,而组件是和模板紧密关联的,组件模板和组件逻辑分离让问题复杂化了。所以就有了 JSX 这种语法,就是为了把 HTML 模板直接嵌入到 JS 代码里面,这样就做到了模板和组件关联,但是 JS 不支持这种包含 HTML 的语法,所以需要通过工具将 JSX 编译输出成 JS 代码才能使用。
(2)JSX基本语法
1.小写的字符串是 HTML 标签,大写开头的变量是 React 组件。
2.HTML 里的 class 在 JSX 里要写成 className,因为 class 在 JS 里是保留关键字。同理某些属性比如 for 要写成 htmlFor。
3.表达式
属性值使用表达式,只要用 {} 替换 “”。
表达式是非常强大的,我们可以使用它在JSX标签间或属性中放置js的各种表达式或函数实现各种功能。
子组件也可以作为表达式使用,如:
// Input (JSX):
var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
// Output (JS):
var content = React.createElement(Container,null,window.isLoggedIn ? React.createElement(Nav) : React.createElement(Login)
);
4.JSX注释:
在< >内部可使用js的注释,如果在一个组件的子元素位置使用注释要用 {} 包起来。
5.自定义 HTML 属性:
如果在 JSX 中使用的属性不存在于 HTML 的规范中,这个属性会被忽略。如果要使用自定义属性,可以用 data- 前缀。
6.属性扩散:
使用es6的写法,可给组件设置多个属性,如:
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
props 对象的属性会被设置成 Component 的属性。
另外,jsx中:
style 属性接受由 CSS 属性构成的 JS 对象
onChange 事件表现更接近我们的直觉(不需要 onBlur 去触发)
(3)组件
组件的两个核心概念:props和state。
1.props
props 即组件的属性,由外部通过 JSX 属性传入设置,一旦初始设置完成,就可以认为 this.props 是不可更改的,所以不要轻易更改设置 this.props 里面的值(虽然对于一个 JS 对象你可以做任何事)。
2.state
state 即组件的当前状态,可以把组件简单看成一个“状态机”,
根据状态 state 呈现不同的 UI 展示。一旦状态(数据)更改,组件就会自动调用 render 重新渲染 UI,这个更改的动作会通过 this.setState()来触发。
划分状态的原则:让组件尽可能地少状态,便于组件易维护。
当更改某个数据需要更新组件 UI 的就可以认为是 state。
3.无状态组件
也可以用纯粹的函数定义无状态组件(没有状态和生命周期,只简单的接受 props 渲染生成 DOM 结构)。
无状态组件非常简单,开销低,可能的话尽量去使用无状态组件。比如使用箭头函数定义:
const HelloMessage = (props) => <div> Hello {props.name}</div>;
render(<HelloMessage name="John" />, mountNode);
因为无状态组件只是函数,没有实例返回,这点在想用 refs 获取无状态组件的时候要注意。
4.组件生命周期
1.初始化 this.state 的值,只在组件加载之前调用一次。
ES6中可以在构造函数中初始化状态,如:
class Counter extends Component {constructor(props) {super(props);this.state = { count: props.initialCount };}render() {// ...}
}
2.加载(渲染)组件触发的生命周期函数:
componentWillMount()
只在加载之前调用,在 render 之前调用,可以在这个方法里面调用 setState 改变状态,并且不会导致额外调用一次 render
componentDidMount()
只在加载完成之后调用,在 render 之后调用,从这里开始可以通过 ReactDOM.findDOMNode(this) 获取到组件的 DOM 节点。
3.更新(重新渲染)组件触发的生命周期函数:
这些方法不会在首次 render 组件的周期调用。
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
componentDidUpdate
4.卸载组件触发的生命周期函数:
componentWillUnmount
(4)React事件处理
1.绑定事件
例:
...handleClick(e) {this.setState({ liked: !this.state.liked });}render() {const text = this.state.liked ? 'like' : 'haven\'t liked';return (<p onClick={this.handleClick.bind(this)}>You {text} this. Click to toggle.</p>);}...
React 里面绑定事件的方式和在 HTML 中绑定事件类似,使用驼峰式命名指定要绑定的事件类型(比如 onClick)属性为组件定义的一个方法如( {this.handleClick.bind(this)} )。
注意要显式调用 bind(this) 将事件函数上下文绑定要组件实例上,这也是 React 推崇的原则:尽量使用显式的容易理解的js代码。
2.合成事件和原生事件
React 实现了一个“合成事件”层,这个事件模型保证了和 W3C 标准保持一致,“合成事件”提供了额外的好处:事件委托。
“合成事件”会以事件委托的方式绑定到组件最上层,并且在组件卸载(unmount)的时候自动销毁绑定的事件。
原生事件:比如在 componentDidMount 方法里面通过 addEventListener 绑定的事件就是浏览器原生事件。
所有通过 JSX 方式绑定的事件都是绑定到“合成事件”,建议都使用 React 的方式处理事件。
3.给事件处理函数传递参数
方法:bind(this, arg1, arg2, …)
例:
render: function() {return <p onClick={this.handleClick.bind(this, 'extra param')}>;
},
handleClick: function(param, event) {// handle click
}
(5)DOM 操作
大部分情况下不需要通过查询 DOM 元素去更新组件的 UI,只要关注设置组件的状态(setState)。可能在某些情况下确实需要直接操作 DOM。
ReactDOM.render 组件返回的是对组件的引用,也就是组件实例(对于无状态状态组件来说返回 null),注意 JSX 返回的不是组件实例,它只是一个 ReactElement 对象。
例:
// A ReactElement
const myComponent = <MyComponent />// render
const myComponentInstance = ReactDOM.render(myComponent, mountNode);
myComponentInstance.doSomething();
findDOMNode()
当组件加载到页面上之后(mounted),都可以通过 react-dom 提供的 findDOMNode() 方法拿到组件对应的 DOM 元素。
import { findDOMNode } from 'react-dom';// Inside Component class
componentDidMound() {const el = findDOMNode(this);
}
注意:findDOMNode() 不能用在无状态组件上。
Refs
另一种方式是通过在要引用的 DOM 元素上面设置一个 ref 属性指定一个名称,然后通过 this.refs.name 来访问对应的 DOM 元素。
例:
clearAndFocusInput() {this.setState({ userInput: '' }, () => {this.refs.theInput.focus(); //2.});}render() {return (<div><div onClick={this.clearAndFocusInput.bind(this)}>Click to Focus and Reset</div><input
ref="theInput" //1.value={this.state.userInput}onChange={this.handleChange.bind(this)}/></div>);}
如果 ref 是设置在原生 HTML 元素上,它拿到的就是 DOM 元素,如果设置在自定义组件上,它拿到的就是组件实例,这时候就需要通过 findDOMNode 来拿到组件的 DOM 元素。
因为无状态组件没有实例,所以ref 不能设置在无状态组件上,如果想要拿无状态组件的 DOM 元素的时候,就需要用一个状态组件封装一层,然后通过 ref 和 findDOMNode 去获取。
可以使用 ref 到的组件定义的任何公共方法,比如 this.refs.myTypeahead.reset()
Refs 是访问到组件内部 DOM 节点唯一可靠的方法
Refs 会自动销毁对子组件的引用(当子组件删除时)
refs注意:
不要在 render 或者 render 之前访问 refs
不要滥用 refs,比如只是用它来按照传统的方式操作界面 UI:找到 DOM -> 更新 DOM
(6)组件间通信
未完待续
(7)Mixins
未完待续
(8)Redux
可以参考我关于Redux的总结,后续还会不断进行完善:
http://www.atatech.org/articles/58588
React相关参考资料:
React中文网:
http://reactjs.cn/
React中文社区:
http://react-china.org/
React/React Native 的ES5 ES6写法对照表:
http://bbs.reactnative.cn/topic/15/react-react-native-%E7%9A%84es5-es6%E5%86%99%E6%B3%95%E5%AF%B9%E7%85%A7%E8%A1%A8
React.js读书与总结:《react-tutorial》相关推荐
- React.js 小书 Lesson5 - React.js 基本环境安装
React.js 小书 Lesson5 - React.js 基本环境安装 本文作者:胡子大哈 本文原文:http://huziketang.com/books/react/lesson5 转载请注明 ...
- React.js 开发常见问题
React.js 开发常见问题 我需要为 React.js 雇用专门的开发人员,还是说只要会 JavaScript 的员工就行? 如果你有了一支熟练的 JavaScript 开发团队,那么使用 Rea ...
- React.js 2016 最佳实践 徬梓阅读 1584收藏 71
为什么80%的码农都做不了架构师?>>> 译者按:近几个月React相关话题依旧火热,相信越来越多的开发者在尝试这样一项技术,我们团队也在PC和移动端不断总结经验.2016来了 ...
- 撰写本文的所有基本React.js概念
Update: This article is now part of my book "React.js Beyond The Basics". 更新:本文现在是我的书<超 ...
- 在React.js中执行反跳
本文翻译自:Perform debounce in React.js How do you perform debounce in React.js? 您如何在React.js中执行反跳? I wan ...
- react.js开发_2020 React.js开发人员路线图
react.js开发 成为阅读JS开发人员的插图指南,其中包含相关课程的链接 React JS或简称React是用于开发Web应用程序的前端或GUI的领先JavaScript库之一. 在Faceboo ...
- react 学习路线_2018 React JS路线图
react 学习路线 成为阅读JS开发人员的插图指南,其中包含相关课程的链接 React JS或简称React是用于开发Web应用程序的前端或GUI的领先JavaScript库之一. 在Faceboo ...
- 使用 React.js 开发 Chrome 插件
(点击上方公众号,可快速关注) 来源:UncleChen unclechen.github.io/2017/06/16/使用ReactJS开发Chrome插件/ 一.背景 相信看到这篇文章的人应该都用 ...
- cherrypy@Tutorial 10:Mak ita modern single-pageapplication wth React.js
近年来,客户端单页应用程序(SPA)逐渐吞噬了服务器端生成的内容Web应用程序的午餐. 本教程演示了如何与React.js集成,React.js是2013年由Facebook发布的SPA的Javasc ...
最新文章
- 小明种苹果python_Python实现201909-2(小明种苹果(续))满分代码,带注释
- Python 2.7 Exception格式化工具
- Android makefile编译流程(二)
- cat命令读取一部分_脚本攻略2 --命令之花
- http请求curl
- 康普顿效应是弹性碰撞吗_【量子力学】康普顿散射与逆康普顿散射
- Go的闭包看你犯错,Rust却默默帮你排坑
- 智能录音笔完成全系列布局,科大讯飞还发了一款转写翻译智能耳机
- Django uplodify 多文件同时上传
- [Data Structure Algorithm] 有向无环图的拓扑排序及关键路径
- WordPress安装插件提示输入FTP账户信息
- 3道js面试题引发的脑洞
- 一小时学会Python3爬虫基础(七)高级数据的全部操作:列表
- css div img等元素居中对齐
- stm32 USB HID+CDC 鼠标键盘串口 组合设备配置解析
- 苹果序列号查询api查询序列号和苹果产品信息
- Android_Vibrator(振动器)使用解析
- jsp中给div加背景_html中给元素添加背景图片或者gif动图
- 计算机电源怎么设置玩游戏不卡,端游绝地求生怎么设置不卡
- 计算机毕业设计ssm客房订餐系统s2whx系统+程序+源码+lw+远程部署