React使用ES2015符号"tag"它的元素对象.
它在旧版浏览器上使用幻数作为回退.
React使用虚拟DOM元素,这成为真实的DOM在渲染上的元素.
虚拟DOM元素可以被定义为一个简单的对象文字.
通常你会使用React. createElement()创建一个元素.
这就是a的返回值React. createElement()电话可能看起来像.
这个特殊的财产将被检查React确保这个对象是一个React元素而不仅仅是一些用户数据React.createElement()为你设置
这也将被检查React.
我们稍后将讨论引用,但如果您不使用它们,则必须将其设置为null,而不是未定义的
这定义了HTML标签
这定义了传递给元素的属性
在这个例子中,只有一个文本节点作为子节点aCSS类
样式可以作为对象文字传递React使用camelCase而不是虚线 (例如CSS/D3做)
事件处理程序也可以作为属性添加React使用综合事件,基本上试图规范化浏览器的行为
另一个没有太多配置的元素React需要一个DOM元素作为渲染目标
ReactDOMOM负责将元素插入到DOM中
React.createElement()需要类型,属性,孩子. 这比使用普通对象文字的冗长,它隐藏了第0课中提到的$$ type / Symbol和ref
第二个参数是属性对象,如果为空,则必须为null
现在我们将使用JSX,这需要转换为JavaScript. 为此我们将使用Babel. Babel通常用于转换ES2015至ES5,但它也可以转换JSX至ES5. Babel浏览器版本使用文本/ babel脚本标签.
JSX是创造元素的惯用方式. 基本上是这样XHTML同{}对于动态内容,也必须将class称为className
是相同的
JSX特别是构成大多数的简单元素尤其闪耀
是相同的
正如我们所看到的,其他一切和以前一样
元素可以嵌套,这将导致嵌套React.createElement()reateElement调用正如你可以想象的那样,不需要写这个JSX会很乏味
他们也可以像第2课中提到的那样包含JavaScript在{}
JavaScript插入在属性中的语法与在普通文本或元素中的语法相同
这个JavaScript也可以包含元素,也可以将对象"散布"为属性
主要卖点之一React是它的组件系统组件被用来封装元素和它们的行为,将它们视为MVC的控制器和视图的混合
这里我们使用独立元素和一些数据
这里的元素被封装在一个简单的组件函数中它们必须以大写字母开头,并返回恰好一个根元素 (带或不带嵌套元素) (之前React16)
以来React16.0.0,组件也可以返回元素数组. 为此,不创建额外的包装器元素. 有一点需要注意的是,与我们在渲染数组时所做的相似,我们必须为数组中的每个元素添加一个唯一键 (在下一课中我们会看到更多内容)
以来React16.2.0,我们可以使用称为片段的特殊"包装器"组件,它们的行为相同 (不创建额外的包装器元素) ,但是不需要设置明确的键 (片段可以在引擎盖下进行)
一个组件函数可以像一个元素一样使用
这转化为aReact.createElement()调用null表示没有设置属性
供参考React-内部<div>标签
被转换为
组件与元素一样也可以使用属性
这也适用于对象和传播 (...) 运算符
这允许具有动态内容的组件
如果一个数组被用作"子节点",那么每个孩子都需要一个唯一的键属性
PropType已从中删除React16,现在是他们自己的套餐
组件被创建来封装应该在一起的东西并重用. 重复使用要求组件的用户提供正确的属性,以便我们可以定义每个属性的类型并设置默认值
将propTypes (function-) 属性添加到组件函数以使其验证其 ( (element) ) 属性
React为我们提供了一堆类型,比如字符串
如果用户未提供任何内容,则添加defaultProps (function-) 属性以设置默认值
这将在控制台中显示警告,因为customData应该是一个字符串
这将使用默认值
这是一个更实用的组件格式化日期并返回一个例子<span>包含格式化的字符串
还有一个更复杂的日期属性类型检查该属性是必需的,因为没有设置默认值
我们必须提供一个日期对象,组件进行格式化
组件与元素一样可以嵌套
为此,子组件内部使用子属性
这个组件只是将它的孩子包裹在一个<li>元件
这个组件把它的孩子包装成一个<ul>元件
如果<List>没有孩子的时候会创建一个默认的孩子
现在我们渲染两个<List>没有和有物品
React.createElement()reateClass已从中删除React16现在是它自己的软件包
通常情况下,组件需要维护一些内部状态,例如,如果在这种情况下涉及交互,则组件功能不够,组件功能只能具有属性而没有状态,我们需要具有渲染功能的组件类
用于与组件函数相同的属性类型检查
此方法为缺少的属性设置默认值,它将被调用React在组件被装入DOM之前
这个方法为它将被调用的组件设置初始状态React如果缺少这种方法,组件被装入DOM之前,this.state将是未定义的
国家可以是任何JavaScript价值,往往是一个对象
此方法处理所有的点击<span>元件
可以使用包含新状态的对象调用setState () ,但通常会触发render () 的调用React可以批量多次调用并延迟render () 调用 (使调用异步) 为了防止出现这种情况,setState可以取回一个回调
如果我们依赖,这可能会导致意想不到的行为this.state要么this.props为我们的计算this.setState ({时间: this.state.times+ 1})
回调版本没有这个问题回调得到正确的状态和props在更新时
这个方法会被调用React每次将组件装入DOM之后this.setState () 被称为它就像之前的组件函数,但没有props论据
使用该组件属性的创建者给出的道具现在处于this.props而不是props论据
通过点击处理程序返回一个元素props和状态值. 状态存储在this.state
创建一些具有默认颜色的交互式有状态组件类的实例一切与更简单的组件函数完全相同对于此组件的用户,接口没有改变
一个简单的例子React应用程序它为无状态组件使用简单的组件函数,并使用复杂的组件类来处理交互
首先我们有任务和任务列表他们通过他们的属性获得他们所有的数据/状态<TaskList>
<Task text="Do something"/>
<Task text="Do nothing"/>
</TaskList>
任务需要一个文本属性
TaskList需要在其子属性中包含任务数组
打印第一个粗体元素
这个组件处理输入它需要是一个类,因为<input>元素是有状态的
当有人输入进来时被调用<input>元件
当有人点击时会被调用<button>元件
调用添加到其onAdd属性中的函数
请清除状态,以便在添加后再次输入为空
每次有人输入或添加时呈现元素
该应用程序跟踪其状态中的当前任务
这个回调会被插入到onAdd属性中<TaskInput>零件
增加一项新任务
这迫使了<TodoApp>要渲染的组件
创建列表<Task>组件来自任务数组中的状态
一些简单的样式和添加处理程序的<TaskInput>零件
我们可以直接使用组件
如果我们使用组件类,我们的组件会继承一堆被调用的方法React在特定的时间让我们对我们的组件有更多的控制,其中一些我们已经在第9课中遇到过. 这里有几个新组件. 不是全部,而是最重要的
这个方法是在默认的prop值之前被调用的props给我们的组件"真实"props如果有的话,覆盖它们
这个方法在组件被装载到DOM之前被调用,它返回用于的值this.state
在装载组件之前调用此方法可用于初始化某些同步配置,该配置在组件呈现前应该可用
这个方法在组件被挂载后立即调用,这是启动一些异步任务的好地方. 例如,在第一个mount上显示一个加载消息,然后调用componentDidMount并获取一些服务器数据.
我们清理数据并从某处获得新的信息
初始数据加载
我们每4秒模拟一次服务器请求
这个方法在组件从析构函数中被移除之前被调用. 在这里,我们可以做一些清理.
新方法在渲染之前调用此方法props或状态是可用的,它不会在第一个渲染或如果调用this.forceUpdate()如果某些状态或道具变化不需要重投,可以使用它
我们想要在每次更改时渲染,这是默认行为
重构是另一件很好的事情React首先,我们将讨论如何将一个组件重构为另一个组件,您可以更改组件的实现,而无需在呼叫站点更改任何内容
我们从一个以某种方式呈现记录的组件开始
该组件有一个简单的props-接口
现在我们用更复杂的东西来切换实现
我们保持props- 接口相同
我们也可以用更动态的东西切换它
我们仍然保持着props- 接口相同
一些数据
正如我们所看到的,组件的使用方式完全相同如果我们将ViewAfter的实现复制到ViewBefore中,所有内容都可以继续工作
重构一个元素有点棘手首先,JSX确定标签是否是元素或组件是小写的意思是元素的大写意味着组件
变
变
第二,React将这些元素触发的所有事件转换为合成事件. 这通常不是问题,它们仅仅是事件. 但你不能触发你自己的. 所以,即使你的<Input>组件接受一个onClick作为属性回调你不能用一个相同的事件来调用它<input>元素会
一种方法可能是这样的. 我们只是实现我们自己的onChange调用者在这里,我们创建一个只能调用的数字输入onChange在数字输入 (非数字触发一个空的变化)
我们可以尝试修改事件来获取我们的数据,但这可能会让事情搞砸,而不是我们阻止此事件进一步采取行动
过滤空白变化
然后我们提取我们的数据并提供给它onChange
在这里我们看到,新的NumberInput具有不同的接口onChange财产意味着会收到事件,但事实并非如此. 另外,即使我们想把它称为原始输入,我们也需要使用大写字母,并且不会赢得任何东西
其他方法包括不首先在onUpdate中使用"默认"prop属性名称onChange
它也可能发生,一个组件使用onMouseDown做一些内部的事情并触发一个onChange,这可能会导致混淆通常组件比第一个元素提供更丰富的交互,所以它们的prop方法可以用名称来反映
有时我们需要某个元素或某个组件的状态,或者必须以某种方式直接进行修改. 对于这种情况,我们可以告诉React创建参考.
首先我们告诉React使用ref回调来呈现输入时,将会调用它DOM的输入元素是可用的
当input元素被装载到DOM中时调用此回调函数,并且当它再次被卸载时再次调用null. 对于呈现元素DOM节点将被存储对于组件,组件的实例将被存储.
我们保存对其的引用以备后用.
此按钮被单击并使用时调用此回调this.nameInput读出输入的值.
由于引用对其组件是局部的,因此它们可以用作本地ID来获取元素,并且在创建组件的另一个实例时不会相互覆盖
大多数情况下,我们必须在应用程序中使用第三方库. 在这里,我们整合了一个简单的日期处理和使用它React. 它不使用DOM所以它可以很容易地集成.
被称为同步的简单库可以直接用于JSX在...的帮助下{},因为它们只是函数调用
没有什么令人兴奋的事情发生在这里,只是调用库并显示其返回值. 首先使用一些元素,然后在组件内部使用.
有时我们需要整合更复杂的库. 希望直接使用DOM或需要异步交互的库. 在这个例子中,我们使用了一个免费的InfoVis库D3.js.
由于D3需要直接与之交互DOM我们应该使用一个组件类,因为它可以存储对它的引用DOM-elements.
我们只是渲染一个空的画布并告诉React在渲染之后存储其引用
在第一次渲染之后,我们获取对canvas元素的引用DOM并将其传递给库在这里,我们也使用一些额外的颜色配置
我们对重新渲染也有一些细粒度的控制. 使用这种lifecylce方法
在这里,我们可以告诉我们的图书馆的新数据props或状态,所以它可以更新DOM元素本身
最后,我们总是返回false,所以我们的render方法没有被调用,canvas元素也没有被替换
在从DOM中删除组件之前,可以使用此生命周期方法来释放资源. 我们的画布肯定会被移除,但是对于图书馆,其他对象,听众等来说通常会有状态,他们可以存储在组件上,并且应该被删除以防止内存泄漏
现在我们可以使用该库作为组件不需要全局ID,每个实例都有自己的画布引用存储,也有它自己的颜色属性
将图书馆交互包装成一个功能
来自一个例子hTTP: //bl.ocks.org/mbostock/1b64ec067fcfc51e7471d944f51f1611its realeased under theGPL-V3`