ReactDOM.render()
ReactDOM.render() 是react的基本用法,是将模板语言转换成html语言,并插入指定的dom节点。
上面代码将一个 h1 标题,插入 example 节点(查看 react-demos edemo01)
JSX语法
HTML语言直接写在js语言中,不加任何引号,这就是jsx的语法,它允许HTML与JavaScript的混写。
上面代码体现了jsx基本语法规则:遇到html标签,就用html规则解析;遇到代码块以{开头,就用JavaScript规则解析。
jsx允许直接在模板插入JavaScript变量。如果这个变量是一个数组,则会展开这个数组所有成员。
上面的代码names 变量是个数组,结果jsx会把所有成员添加到模板。
#### 组件
React 允许将代码封装成组件(component),然后像插入普通HTML标签一样,在网页中插入这个组件。React.createClass 方法就用于生成一个组件类。
上面的代码中,变量HelloMessage 就是一个组件类。模板插入时,会自动生成HelloMessage 的一个实例。所有的组件类都必须有
自己的render 方法,用于输出组件。
注意!组件类的第一个字母必须大写,否则会报错,比如HelloMessage 不能写成helloMessage。另外,组件类只能包含一个顶层标签,否则也会报错。
上面代码会报错,因为HelloMessage组件包含了两个顶层标签:h1和p。
组件的用法与原生的 HTML 标签完全一致,可以任意加入属性,比如 ,就是 HelloMessage 组件加入一个 name 属性,值为 John。组件的属性可以在组件类的 this.props 对象上获取,比如 name 属性就可以通过 this.props.name 读取
添加组件属性,有一个地方需要注意,就是 class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。
this.props.children
this.props 对象的属性与组件的属性一一对应,但是一个例外,就是this.props.children 属性,它表示组件的所有子节点。
上面代码的 NotesList 组件有三个span 子节点,他们都可以通过 this.props.children 读取。
这里需要注意,this.props.children 的值有三种可能:当前组件没有子节点 他就是 undefind;如果有一个子节点,数据类型是object;如果有多个子节点数据类型就是 array 。所以 处理this.props.children 的时候要小心。
React 提供一个工具方法 React.Children 来处理 this.props.children 。我们可以用 React.Children.map 来遍历子节点,而不用担心 this.props.children 的数据类型是 undefined 还是object。
PropTypes
组件的属性可以接受任意值,字符串,对象,函数等等都可以。有时有时,我们需要一种机制,验证别人使用组件时,提供的参数是否符合要求。
组件类的 PropTypes属性,就是用来验证组件实例的属性是否符合要求
上面的MyTitle组件有一个title 属性。PropTypes 告诉React,这个 title 属性是必须的,而且它的值必须是字符串。现在我们设置 title
为一个数值。
这样一来,title属性就通不过验证了。控制台会显示一行错误信息。
此外,getDefaultProps 方法可以用来设置组件属性的默认值。
会输出hello world。
获取真实的DOM节点
组件并不是真实的DOM节点,而是存在于内存之中的一种数据结构,叫做虚拟DOM。只有当它插入文档之后,才会变成真实的dom。根据React的设计,
所有的dom变动都先在虚拟的DOM上发生,然后再将实际发生变动的部分,反映到真实的Dom上,这种算法叫做DOM diff,它可以极大提高网页性能表现。
但是有时候需要从组件获取真实DOM的节点,这时就要用到 ref 属性。
上面代码中,组件MyComponent 的子节点有一个文本框,用于获取用户的输入。这时就必须获取真实的dom节点,虚拟dom是拿不到用户输入的,为了做到这一点。文本框有一个ref
属性,然后this.refs.[refName] 就会返回这个真实的DOM 节点。
需要注意的是,由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取 this.refs.[refName] 属性。
React 组件支持很多事件,除了 Click 事件以外,还有 KeyDown 、Copy、Scroll 等,完整的事件清单请查看官方文档。
this.state
组件免不了要与用户互动,react的一大创新,就是将组件看成一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染UI.
上面代码是一个LikeButton 组件,它的getInitialState 方法用于定义初始状态 。也就是一个对象,这个对象可以通过this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法去修改状态值,每次修改以后
自动调用 this.render 方法再次渲染组件。
由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。
表单
用户在表单填入的内容,属于用户跟组件的互动,所以不能用 this.props 读取(查看 demo9 )。
上面代码中,文本输入框的值,不能用 this.props.value 读取,而要定义一个 onChange 事件的回调函数,通过 event.target.value 读取用户输入的值。textarea 元素、select元素、radio元素都属于这种情况,更多介绍请参考官方文档。