reactjs elment 和conpoment有什么区别

当前位置: &
求翻译:Electronic conpoment是什么意思?
Electronic conpoment
问题补充:
正在翻译,请等待...
电子conpoment
电子conpoment
电子 conpoment
电子conpoment
我来回答:
参考资料:
* 验证码:
登录后回答可以获得积分奖励,并可以查看和管理所有的回答。 |
我要翻译和提问
请输入您需要翻译的文本!标签:至少1个,最多5个
工欲善其事必先利其器, 因为react崇尚的是, react一体化. 即, 使用js拯救世界. 所以, 我们需要先将支持react的webpack 工具解决.
webpack 配置
这里主要使用的是这些模块:
"babel-loader": "^6.2.4",
"babel-core": "^6.8.0",
"babel-loader": "^6.2.4",
"babel-plugin-transform-es2015-arrow-functions": "^6.8.0",
"babel-preset-es2015": "^6.6.0",
"react-dom": "^15.2.1",
"react" : "^15.2.1"
将这些文件放到package.json中,然后使用npm install 即可.这里就不赘述了. 先放一个最简单的webpack.config.js文件.
var path = require('path'),
node_modules = path.resolve(__dirname, 'node_modules');
module.exports = {
// context: __dirname + "/app/src/entry",
app:"./dev/app"
}, //演示单入口文件
path: path.join(__dirname, '/dev/dist'), //打包输出的路径
filename: '[name].entry.js', //打包后的名字
loaders: [{
test: /\.js|\.jsx$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel?presets[]=es2015' //加载使用loader
plugins: [
watch: true
这里需要注意一下, 由于版本的问题, webpack 在v1.13之后, 会默认给entry文件添加extensions. 所以如果你的entry写成了,./dev/app.js的话, 恭喜你, 踩坑了. 如果万一出错了, 你可以使用
webpack --display-error-details
来进行排查. ok , 现在我们正式进入react时间
react 入门
初期, react基本的操作无外乎就是围绕着,Component和ReactDOM进行编写和渲染。 以前, react并没有分的太细化, 不过在version 0.14版本后, ReactDOM和Component就分开了, 主要还是因为React Native的缘由. 不过, 两者分开过后,造成的影响来说, 还是不小的. 主要影响到三个方面:
ReactDOM.render(): 渲染UI层
ReactDOM.findDOMNode(): 获取节点
ReactDOM.renderToString(): 后端运用的转义String方法
上面, 我们已经下载好了react和react-dom. 我们可以来简单看一个demo:
import React,{Component} from 'react';
import ReactDOM from 'react-dom';
class Hello extends Component{
&h1&Hello world&/h1&
ReactDOM.render(&Hello /&,document.getElementById('container'));
重要的是Hello 类中的render方法. 通过return, 返回虚拟的DOM, 然后经过ReactDOM将虚拟的DOM, 渲染到指定节点内部.
假如我们现在想要在render中, 使用变量,so how to do?很简单, 只要在DOM里面用到curly braces({})即可.
class Hello extends Component{
let name="jimmy";
&h1&Hello {name}&/h1&
React之所以这么流行,就是因为他的可复用性. 通过& classname /& 这样的调用, 就可以完美的实现, 组件的复用
class UI_item extends Component{
class UL extends Component{
&Li_item name="jimmy"&ok&/Li_item&
&Li_item name="sam"&yes&/Li_item&
class Li_item extends Component{
&li&my name is {this.props.name} & and my content is {this.props.children}&/li&
在进行组件复用时, 重用UI 和写HTML一样, 使用闭合标签,添加属性等等. 不过,这里需要注意一下, 在JSX语法中, class属性需要换成 className(因为内部冲突).另外, 提及一下上文出席那的两个内容. this.props.xx 和this.props.children
this.props.xxx : 是用来获得节点中的属性内容. 比如: name, data-name,data-set等等.
this.props.children: 用来获取闭合tag中的内容. 比如: & div&abc& /div& 获取得到为: abc
this.props 在组件复用中,是占很重要的地位的, 可以说,他是parent和children 组件通信的重要通道, 父组件 赋值, 子组件处理. like:
通常来说, 写一个整体的UI 有两种方式, 一种是Top-Down, 一种是Bottom-Up. 两者都行, 只是思考的方式不一样, 不过一般TD(自顶向下)方式比较普遍些.
如果你想利用循环生成jsx的话, 可以使用:
class UL extends Component{
let tasks = [];
for(var i=1,len=this.props.i&=i++){
tasks.push(
&Li_item key={i} number={i}&list&/Li_item&
但需要注意的是, 你不能直接写为:
如果这样写的话,react是不会让你通过的. 因为他认为你这个是不合法数据, 一般来说, 不能在第一层里面直接写入: arrar,object 对象.
react 提供另外一个状态属性-this.state. React 通过改变父组件本身的state, 会导致DOM的重新渲染, 相当于重新调用ReactDOM.render().
have a try
这里, 我们通过简单的改变, 父组件的state, 来实现节点的重流和重绘.实现的demo 放在上, 可以参考一下. 这里我只贴精华的demo:
class UI_item extends Component{
constructor(){
this.state={
origin:true
let number = 5;
if(!this.state.origin){
number*=2;
&button onClick={()=&{this.doubleNumber()}}&&/button&
&UL number={number}&&/UL&
doubleNumber(){
this.setState({
origin:!this.state.origin
上面的代码其实有点绕的. 这里补充几点, 相信看过之后,再回去看代码也就明白了.
this.setState({xxx:xxx}): 该方法是父组件的专属方法, 其可以手动的修改state的状态, 来实现状态的更新.
this.state: 初始情况下,是在constructor 方法中, 直接设置。 不过, 你也可以放在render 方法中, 这也是没问题的.
事件绑定: React中绑定事件的代码虽然有点奇葩, 但他确实是绑定事件最简洁的办法. 他会在后面的流程中,自动解析事件内容, 然后使用addEventListener进行绑定.
另外, 你新增this.props也是会重新渲染节点的.
结合,上面的this.props 可以大概了解, React 提供的精华架构.
事件绑定解析
React 之所以高性能, 不仅在于虚拟DOM的算法, 事件绑定也在一定程度提升性能. 因为React的所有事件都是绑定在document 根元素上.比较好的绑定方式是,通过函数+bind方法进行绑定的
let number = 5;
if(!this.state.origin){
number*=2;
&button onClick={this.doubleNumber.bind(this)}}&&/button&
&UL number={number}&&/UL&
来看一下,React 提供的事件.from pro react
小心JSX的坑
React 在提出本身的同时, 也提出了JSX语法. 这是为什么呢? 我们可以看一下,React 是如何翻译JSX语法, 你就应该知道为什么JSX很受欢迎~
&h1&Hello World&/h1&
// React 方法调用
React.createElement("h1", null, "Hello World");
当你写出JSX 的时候,React在背后已经帮你解析成对应的方法了. 所以, 这样隐形的API, 为什么不用呢?不过JSX 中有部分内容需要注意一下.
驼峰命名的属性
在JSX中, 给tag添加属性时,需要使用驼峰命令. 即.
&input type="text" name="usrname" maxlength="10"&
&input type="text" name="usrname" maxLength="10"&&br&
但像,这样的data-set 使用dash连接的就不需要额外的注意. 另外, react 特别强调了class需要写为className. 因为在React内容,class 存在冲突, 所以强制性将class property改为了className.
很简单, 就是所有标签必须闭合. 比如像&img src="..."&这样的, 后面的/ 可以写可不写. 但是, 现在在JSX中,所有的都必须写.
&img src="..." /&
only one node
这里,应该是很多初入React 童鞋常常犯的~ 可能对函数的了解还未透彻. 比如一个函数:
function add(){
return (1,2);
上面的结果是多少?很简单是2. 这是解析引擎所决定的. 因为, 直接通过return 语句返回, 永远只能返回一个值.所以, 这也决定了在React中, 你使用render返回JSX时, 只能带上一个节点.
&h1&Hello World&/h1&
&h1&Hello World&/h1&
&h2&Have a nice day&/h2&
改写一下, 你只能返回一个节点:
&h1&Hello World&/h1&
&h2&Have a nice day&/h2&
don't use if-else
在JSX, 一般不要乱用if-else. 因为if-else 是不会返回任何值的。
&li data-set={if(true){"ok"}}&jimmy&/li&
推荐情况是, 使用三元运算(ternary). 因为他可以返回值.
&li data-set={true?'ok':0}&jimmy&/li&
置于为什么, 我们可以在这里剖析一下JSX语法的结构. 前文已经提到了, JSX其实就是React.createElement(). 我们的属性其实,就是当做createElment参数的
&div className={if (condition) { "salutation" }}&Hello JSX&/div&
React.createElement("div", {className: if (condition) { "salutation"}}, "Hello JSX");
这里, 有点基本常识的应该知道, 对象里面怎么执行... 除非你有返回值.
React在渲染的时候,会默认忽略掉元素间的空格. 估计是考虑到了inline-block 造成的3~4px的影响.
&li &{this.props.children}_{this.props.number}
&a href=""&ok&/a&
&a href=""&yes&/a&
这样渲染的结果是
不过, 如果你仅仅是填写文本的话, 里面的空格就不会被忽略。如果, 你想在元素之间添加上空格的话. 可以这样写:
&a href=""&ok&/a& {" "}
&a href=""&yes&/a&
在JSX中,写评论的话, 需要注意他的注释方式:
/* comment */
另外,如果你的注释是childElement, 则需要使用{}括起来. 但在元素内部评论的话,就不需要了
{/* this is a child comment */}
/* multi line
comment */
name="sam" // end of line comment
上面的demo 基本上把所有注释情况都包含了.
动态插入HTML
以前,我们纯原始写组件的时候, 常常利用的就是element的innerHTML属性. 即, 直接在html tag里面添加string, 然后利用内部渲染,将element渲染出来.
{this.dynamicP()}
// 动态脚本
dynamicP(){
let p = "&p&123&/p&";
但是, 这样容易犯的一个错误就是XSS, 因为XSS最常用的手段就是动态恶意脚本的插入. 有兴趣的童鞋,可以参考一下我的.React考虑到这点, 果断将所有一切插入的String进行转义.所以, 上面渲染出来的会是这样的:
当有时候,我们又不得不使用动态的String当做HTML插入, 那应该怎么做呢?官方给出的解决办法是, 使用dangerouslySetInnerHTML这个属性.
&span dangerouslySetInnerHTML={{__html:dynamicP()}} /&
这样, React就会对插入的HTML解除XSS的限制.
为什么说表单输入在React里面也是一块需要注意的呢?因为, 一旦你设置在input的value属性. 后面你所有的输入都是无效的.
&input type="search" value="React" /&
so how to solve it?这里就需要使用onChange和this.state来帮助我们进行重绘.
class Search extends Component {
constructor(){
this.state={
value:"React"
render() {
return ( &div&
Search Term: &input type="search" value={this.state.value} onChange={this.handleChange.bind(this)} /& &/div&
handleChange(event){
this.setState({
value:event.target.value
通过输入,触发onChange, 然后onChange 触发this.setState, 重新渲染DOM。get~
另外,表单输入,还需要注意另外两个ele. textarea和select.
textArea 在React中, textarea的书写格式和HTML中有些不同
&textarea&This is the description.&/textarea&
&textarea value="This is a description." /&
该element 也需要绑定onChange时间才行.
select 元素的写法和原始HTML差别不大,只是里面的选取默认的option需要改变一下。 在HTML中, 书写默认的option 只需要添加selected属性即可. 但在React, 则需要手动指定value才行.
&select value="B"&
&option value="A"&A&/option&
&option value="B"&B&/option&
&option value="C"&C&/option&
反模式表单
这里所谓的anti-pattern(反模式) 听起来逼格挺高的. in fact, 他还是表单. 只是你不用写value属性. 而这里的反模式实际体现在, 你不用绑定onChange事件, 元素中的内容,也能随着用户的输入自动变化.看个demo:
render() {
controled component
type="text" value="fixed" /&&br/&
uncontroled component
&input type="text" /&
线上demo请参考: 那 uncontroled component 和 controled component 之间的区别是神马嘞?简而言之, 如果你的表单需要有很多限制那么就用controled component, 如果没有可以考虑uncontroled.
我们总结一下:
内部属性trick
React 以他Virtual DOM 而闻名遐迩, 通过造出一个Virtual DOM, 然后, 通过一种比较算法,得出最新的DOM结构, 从而让页面性能损耗降到最低. 现在我们考虑一种情况.即, 渲染重复的list.即:
当其中的几个节点需要变为:
&li&1&/li&
&li&2&/li&
React会怎么做... 他首先会提示你, 孩纸, 你这样不行... 因为, 这样的实现方法是在是太多了. CRUD 哪一种都可以实现上述行为. 所以,React需要你手动的设置一个key值,来帮助他标识, 你改动的list是哪一个~上面的render我们就需要改为:
render() {
let lis = [];
for(var i=0;i&4;i++){
lis.push((
&li key={i} &{i}&/li&
谨慎的refs
refs 实际上是一种,黑魔法,又可以称为语法糖. 因为他不需要我们手动的使用document.getElementxxx 来获取节点. 他已经帮你把dirty work 给干好了. 我们只需要使用this.refs.xx 来获取指定节点即可. 但是, 官方是不提倡这种做法的,因为这样破坏了数据的流向性. React本来是用过render, 来改变元素的状态, 但是, 如果从外面使用this.refs 改变 DOM的话, 有可能会造成virtual DOM和actual DOM不统一的情况.如果你真的想用的话, 那就需要使用ref了, 这样至少可能保证DOM状态的统一. 可以说, 在React中,你基本上可以和document.xxx系列说拜拜了.
constructor(){
this.number = 0;
render() {
&button onClick={this.clickButton.bind(this)}&click me&/button&
&span ref="text"&I will be changed&/span&
clickButton(){
let text = this.refs.
text.innerHTML = this.number++;
注意一下, 属性书写是用ref, 获取是使用refs. 线上demo, 参考:
0 收藏&&|&&14
你可能感兴趣的文章
4 收藏,662
9 收藏,5k
8 收藏,619
本作品 保留所有权利 。未获得许可人许可前,不允许他人复制、发行、展览和表演作品。不允许他人基于该作品创作演绎作品
input设置默认值官方是使用defaultValue={value},而不是把value放在state里维护,另外onChange事件是输入框失去焦点时触发而不输入时,所以放在onChange事件里更新value是有问题的
分享到微博?
你好!看起来你挺喜欢这个内容,但是你还没有注册帐号。 当你创建了帐号,我们能准确地追踪你关注的问题,在有新答案或内容的时候收到网页和邮件通知。还能直接向作者咨询更多细节。如果上面的内容有帮助,记得点赞 (????)? 表示感谢。
明天提醒我
我要该,理由是:共被编辑 5 次
一个标志,表示其为一个React Element, 源码如下,有英文解释
// The Symbol used to tag the ReactElement type. If there is no native Symbol
// nor polyfill, then a plain number is used for performance.
var REACT_ELEMENT_TYPE =
(typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element')) ||
var ReactElement = function(type, key, ref, self, source, owner, props) {
var element = {
// This tag allow us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE,
// Built-in properties that belong on the element
type: type,
props: props,
// Record the component responsible for creating this element.
_owner: owner,
补充一下,它存在的作用。
没有加这个$$typeof之前,object被认为是有效的React Element。为了将React Element和普通的对象区分开,
判断React的children是否是一个React Element, 来尽可能防止xss漏洞。
相关文章如下:
一个标志,表示其为一个React Element, 源码如下,有英文解释
// The Symbol used to tag the ReactElement type. If there is no native Symbol
// nor polyfill, then a plain number is used for performance.
var REACT_ELEMENT_TYPE =
(typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element')) ||
var ReactElement = function(type, key, ref, self, source, owner, props) {
var element = {
// This tag allow us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE,
// Built-in properties that belong on the element
type: type,
props: props,
// Record the component responsible for creating this element.
_owner: owner,
表示其为一个React Element, 源码如下,有英文解释
// The Symbol used to tag the ReactElement type. If there is no native Symbol
// nor polyfill, then a plain number is used for performance.
var REACT_ELEMENT_TYPE =
(typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element')) ||
var ReactElement = function(type, key, ref, self, source, owner, props) {
var element = {
// This tag allow us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE,
// Built-in properties that belong on the element
type: type,
props: props,
// Record the component responsible for creating this element.
_owner: owner,
表示其为一个React Element, 源码如下,有英文解释
var ReactElement = function(type, key, ref, self, source, owner, props) {
var element = {
// This tag allow us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE,
// Built-in properties that belong on the element
type: type,
props: props,
// Record the component responsible for creating this element.
_owner: owner,
表示其为一个React Elment, 源码如下,有英文解释
var ReactElement = function(type, key, ref, self, source, owner, props) {
var element = {
// This tag allow us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE,
// Built-in properties that belong on the element
type: type,
props: props,
// Record the component responsible for creating this element.
_owner: owner,
我要该,理由是:时间: 01:33:23
&&&& 阅读:51
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&
Introduction
React并不是一个完整的MVC或者MVVM框架,它与Angular也是负责不同的方面,它最大的功能是提供一个高效的视图层。React提供了一些新颖的概念、库和编程原则让你能够同时在服务端和客户端编写快速、紧凑、漂亮的代码来构建你的web应用。如果你使用React,那么可能会涉及到一些常用的概念或技术,包括:
虚拟DOM(virtual DOM)
组件驱动开发(component-driven development)
不变性(immutability)
自上而下的渲染(top-down rendering)
渲染路径和优化
打包工具, ES6, 构建请求, debugging, 路由等
同构React(isomorphic React)
在具体的React实践中,考虑到纯粹的UI或者UX设计人员,他们可能只会将CSS与HTML进行组合,换言之,大量的赋值还是会放置在HTML而非JSX中,建议还是可以运用jQuery+React或者Angular+React的方式。
Virtual Dom
如我们所知,在浏览器渲染网页的过程中,加载到HTML文档后,会将文档解析并构建DOM树,然后将其与解析CSS生成的CSSOM树一起结合产生爱的结晶——RenderObject树,然后将RenderObject树渲染成页面(当然中间可能会有一些优化,比如RenderLayer树)。这些过程都存在与渲染引擎之中,渲染引擎在浏览器中是于JavaScript引擎(JavaScriptCore也好V8也好)分离开的,但为了方便JS操作DOM结构,渲染引擎会暴露一些接口供JavaScript调用。由于这两块相互分离,通信是需要付出代价的,因此JavaScript调用DOM提供的接口性能不咋地。各种性能优化的最佳实践也都在尽可能的减少DOM操作次数。
而虚拟DOM干了什么?它直接用JavaScript实现了DOM树(大致上)。组件的HTML结构并不会直接生成DOM,而是映射生成虚拟的JavaScript DOM结构,React又通过在这个虚拟DOM上实现了一个 diff 算法找出最小变更,再把这些变更写入实际的DOM中。这个虚拟DOM以JS结构的形式存在,计算性能会比较好,而且由于减少了实际DOM操作次数,性能会有较大提升。
React渲染出来的HTML标记都包含了`data-reactid`属性,这有助于React中追踪DOM节点。
单向数据流
在React中,应用利用State与Props对象实现单向数据流的传递。换言之,在一个多组件的架构中,某个父类组件只会负责响应自身的State,并且通过Props在链中传递给自己的子元素。
var FilteredList = React.createClass({
filterList: function(event){
var updatedList = this.state.initialI
updatedList = updatedList.filter(function(item){
return item.toLowerCase().search(
event.target.value.toLowerCase()) !== -1;
this.setState({items: updatedList});
getInitialState: function(){
initialItems: [
"Broccoli",
"Chicken",
"Granola",
"Hash Browns"
componentWillMount: function(){
this.setState({items: this.state.initialItems})
render: function(){
className="filter-list"&
type="text" placeholder="Search" onChange={this.filterList}/&
items={this.state.items}/&
var List = React.createClass({
render: function(){
this.props.items.map(function(item) {
key={item}&{item}&
React.render(/&, document.getElementById(‘mount-point‘));
Quick Start
基本的React的页面形式如下所示:
&!DOCTYPE html&
src="../build/react.js"&&
src="../build/JSXTransformer.js"&&
id="example"&&
type="text/jsx"&
React独创了一种JS、CSS和HTML混写的JSX格式,可以通过在页面中引入JSXTransformer这个文件进行客户端的编译,不过还是推荐在网页端编译,笔者习惯使用Babel这个平台。
HelloWorld
var HelloMessage = React.createClass({
render: function() {
return &Hello {this.props.name}&;
React.render(
name="John" /&,
document.getElementById(‘container‘)
React.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。要注意的是,React的渲染函数并不是简单地把HTML元素复制到页面上,而是维护了一张Virtual Dom映射表。
class ExampleComponent ponent {
constructor() {
this. _handleClick = this. _handleClick.bind(this);
this.state = Store.getState();
Setup:开发环境搭建
完整的React开发环境应该包括了JSX/ES6的解析以及模块化管理,笔者在这里是选用了WebPack与Babel。Webpack是一个强大的包管理以及编译工具,
Webpack是一个非常强大依赖管理与打包工具,其基本的配置方式可以如下:
var path = require(‘path‘);
var node_modules = path.resolve(__dirname, ‘node_modules‘);
var pathToReact = path.resolve(node_modules, ‘react/dist/react.min.js‘);
config = {
entry: [‘webpack/hot/dev-server‘, path.resolve(__dirname, ‘app/main.js‘)],
resolve: {
‘react‘: pathToReact
path: path.resolve(__dirname, ‘build‘),
filename: ‘bundle.js‘,
loaders: [{
test: /\.jsx?$/,
loader: ‘babel‘
noParse: [pathToReact]
module.exports =
Project Structure:项目结构
一个典型的项目结构你可以参考。
webpack.js (js config over json -& flexible)
app/ (the React app: runs on server and client too)
components/
__tests__ (Jest test folder)
AppRoot.jsx
index.js (just to export app)
(only browser: attach app to DOM)
index.html
.gitignore
package.json
Integrated With Angular
Angular与React是笔者喜欢的两个框架,二者可以相辅相成。可以查看笔者的库。
HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是 JSX 的语法,它允许 HTML 与 JavaScript 的混写。
var names = [‘Alice‘, ‘Emily‘, ‘Kate‘];
React.render(
names.map(function (name) {
return &Hello, {name}!&
document.getElementById(‘example‘)
上面代码体现了 JSX 的基本语法规则:遇到 HTML 标签(以 & 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。JSX 允许直接在模板插入 JavaScript 变量。如果这个变量是一个数组,则会展开这个数组的所有成员:
var arr = [
&Hello world!&,
&React is awesome&,
React.render(
document.getElementById(‘example‘)
JSX编译器的核心是将基于XML的语言编译成JS代码,主要是依赖于React.createElment函数。
color="blue" /&;
var app = React.createElement(Nav, {color:"blue"});
var Nav, P
color="blue"&&click&&;
var app = React.createElement(
{color:"blue"},
React.createElement(Profile, null, "click")
JavaScript Expressions
属性表达式
如果需要在HTML中混入JavaScript变量值,需要利用{}来代替”“。
// Input (JSX):
var person = &Person name={window.isLoggedIn ? window.name : ‘‘} /&;
// Output (JS):
var person = React.createElement(
{name: window.isLoggedIn ? window.name : ‘‘}
Boolean Attributes
&input type="button" disabled /&;
&input type="button" disabled={true} /&;
&input type="button" /&;
&input type="button" disabled={false} /&;
Child Expressions
// Input (JSX):
var content = &Container&{window.isLoggedIn ? &Nav /& : &Login /&}&/Container&;
// Output (JS):
var content = React.createElement(
Container,
window.isLoggedIn ? React.createElement(Nav) : React.createElement(Login)
var content = (
{/* child comment, put {} around */}
comment */
name={window.isLoggedIn ? window.name : ‘‘} // end of line comment
Components
React提供了和以往不一样的方式来看待视图,它以组件开发为基础。组件是React的核心概念,React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。React.createClass 方法就用于生成一个组件类。对React应用而言,你需要分割你的页面,使其成为一个个的组件。也就是说,你的应用是由这些组件组合而成的。你可以通过分割组件的方式去开发复杂的页面或某个功能区块,并且组件是可以被复用的。这个过程大概类似于用乐高积木去瓶装不同的物体。我们称这种编程方式称为**组件驱动开发**。
组件的生命周期分成三个状态:
Mounting:已插入真实 DOM,即Initial Render
Updating:正在被重新渲染,即Props与State改变
Unmounting:已移出真实 DOM,即Component Unmount
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):组件判断是否重新渲染时调用
Ini-tial Render
Props Change
State Change
这里可以看出,Props比State的改变会有多出一个shouldComponentUpdate的回调方法。
Com-po-nent Unmount
总结而言,一个完整的React Component的写法应该如下:
var React = require(‘react‘),
MyReactComponent = React.createClass({
getInitialState: function(){
return {};
getDefaultProps: function(){
return {};
render: function(){
return (&&);
// An array of objects each of which can augment the lifecycle methods
mixins: [],
// Functions that can be invoked on the component without creating instances
statics: {
aStaticFunction: function(){}
// -- Lifecycle Methods --
// Invoked once before first render
componentWillMount: function(){
// Calling setState here does not cause a re-render
// Invoked once after the first render
componentDidMount: function(){
// You now have access to this.getDOMNode()
// Invoked whenever there is a prop change
// Called BEFORE render
componentWillReceiveProps: function(nextProps){
// Not called for the initial render
// Previous props can be accessed by this.props
// Calling setState here does not trigger an an additional re-render
// Determines if the render method should run in the subsequent step
// Called BEFORE a render
// Not called for the initial render
shouldComponentUpdate: function(nextProps, nextState){
// If you want the render method to execute in the next step
// return true, else return false
// Called IMMEDIATELY BEFORE a render
componentWillUpdate: function(nextProps, nextState){
// You cannot use this.setState() in this method
// Called IMMEDIATELY AFTER a render
componentDidUpdate: function(prevProps, prevState){
// Called IMMEDIATELY before a component is unmounted
componentWillUnmount: function(){
module.exports = MyReactC
getDefaultProps
设置默认的Props.
Attributes
this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点。
var NotesList = React.createClass({
render: function() {
this.props.children.map(function (child) {
return &{child}&
React.render(
document.body
其效果图如下所示:
Validation
React.createClass({
propTypes: {
optionalArray: React.PropTypes.array,
optionalBool: React.PropTypes.bool,
optionalFunc: React.PropTypes.func,
optionalNumber: React.PropTypes.number,
optionalObject: React.PropTypes.object,
optionalString: React.PropTypes.string,
optionalNode: React.PropTypes.node,
optionalElement: React.PropTypes.element,
optionalMessage: React.PropTypes.instanceOf(Message),
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),
optionalObjectWithShape: React.PropTypes.shape({
color: React.PropTypes.string,
fontSize: React.PropTypes.number
requiredFunc: React.PropTypes.func.isRequired,
requiredAny: React.PropTypes.any.isRequired,
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error(‘Validation failed!‘);
React不提倡数据的双向绑定,而在用户行为下面产生的数据更新,React建议还是通过事件机制来处理。譬如下述例子中,输入框文本内容的改变,还是通过onChange事件,然后出发状态机的变化。
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‘;
&p onClick={this.handleClick}&
You {text} this. Click to toggle.
React.render(
&LikeButton /&,
document.getElementById(‘example‘)
Props与State对比
组件的主要职责是将原始数据转化为HTML中的富文本格式,而Props与State协作完成这件事,换言之,Props与State的并集即是全部的原始数据。Props与State之间也是有很多交集的,譬如:
Props与State都是JS对象。
Props与State的值的改变都会触发界面的重新渲染。
Props与State都是确定性的,即在确定的Props或者State的值的情况下都会得出相同的界面。
不过Props顾名思义,更多的是作为Component的配置项存在。Props往往是由父元素指定并且传递给自己的子元素,不过自身往往不会去改变Props的值。另一方面,State在组件被挂载时才会被赋予一个默认值,而常常在与用户的交互中发生更改。往往一个组件独立地维护它的整个状态机,可以认为State是一个私有属性。他们的对比如下:
是否可以从父元素获取初始值
是否可以被父元素改变
是否可以设置默认值
是否可以在组件内改变
是否可以设置为子元素的初始值
是否可以在子元素中改变
Interactivity and Dynamic UIs
React.findDOMNode()
组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 React.findDOMNode 方法。
var MyComponent = React.createClass({
handleClick: function() {
React.findDOMNode(this.refs.myTextInput).focus();
render: function() {
&input type="text" ref="myTextInput" /&
&input type="button" value="Focus the text input" onClick={this.handleClick} /&
React.render(
&MyComponent /&,
document.getElementById(‘example‘)
需要注意的是,由于 React.findDOMNode 方法获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个方法,否则会返回 null 。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会调用 React.findDOMNode 方法。
getInitialState
设置State的初始状态。
var MyComponent = React.createClass({
getInitialState: function(){
render: function(){
&h1&{this.state.count}&/h1&
Inline-style
在React中,如果要使用行内元素,不可以直接使用style="”这种方式,可以有:
import React from ‘react‘;
var style = {
backgroundColor: ‘#EEE‘
export default React.createClass({
render: function () {
style={style}&
//或者 style={{backgroundColor: ‘#EEE‘}}&
&Hello world&
你可以根据这个策略为每个组件创建 CSS 文件,可以让组件名和 CSS 中的 class 使用一个命名空间,来避免一个组件中的一些 class 干扰到另外一些组件的 class。
app/components/MyComponent.css
.MyComponent-wrapper {
background-color: #EEE;
app/components/MyComponent.jsx
import ‘./MyComponent.css‘;
import React from ‘react‘;
export default React.createClass({
render: function () {
className="MyComponent-wrapper"&
&Hello world&
React对于事件的支持非常完善,可以查看。
TouchEvent
If you’d like to use React on a touch device such as a phone or tablet, simply call React.initializeTouchEvents(true); to enable touch event handling.
譬如在某个子组件中,提供了某个方法:
var ButtonComponent = React.createClass({
getDragonKillingSword: function(){
render: function(){
return ( onClick={this.getDragonKillingSword}&屠龙宝刀,点击就送&);
如果在父组件中想手动调用该方法,则可以利用ref方式:
var ImDaddyComponent = React.createClass({
render: function(){
//其他组件
//其他组件
在父组件的功能方程中:
this.refs.getSwordButton.getDragonKillingSword();
反之,如果需要在子组件中调用父组件的方法,则可以直接将父组件的方法作为Props参数传入到子组件中:
&ButtonComponent clickCallback={this.getSwordButtonClickCallback}/&
组件的数据来源,通常是通过 Ajax 请求从服务器获取,可以使用 componentDidMount 方法设置 Ajax 请求,等到请求成功,再用 this.setState 方法重新渲染 UI。
var UserGist = React.createClass({
getInitialState: function() {
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() {
{this.state.username}‘s last gist is
href={this.state.lastGistUrl}&here&.
React.render(
source="/users/octocat/gists" /&,
document.body
不过笔者习惯还是将整个获取数据,处理数据的业务逻辑放在Angular中进行。
Test:组件测试
对于React组件的测试,这里推荐使用[Jest](https://facebook.github.io/jest/),Jest也是由Facebook提供的测试框架,并且有很多强大的特性,但这里并会详细的介绍它们。关于Jest,我推荐你阅读和尝试来自Facebook的[Tutorial](https://facebook.github.io/jest/docs/tutorial-react.html#content)。对于ES6代码的测试,你可以参考 [React ES6 Testing](/facebook/jest/tree/master/examples/react-es6)。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:&&&&&&&&&&&&
&&国之画&&&& &&&&chrome插件
版权所有 京ICP备号-2
迷上了代码!

我要回帖

更多关于 react redux 的文章

 

随机推荐