React基础知识
ES6版以下几点需要注意
- 不支持 getInitialState 在设置组件初始的 state ,可在组件的 constructor 中通过 this.state 设置,也可直接作为 properties 定义
- propTypes、defaultProps 作为 properties 定义,也可在组件外部通过键值对方式设置。
- 不支持 mixins,可以使用高阶组件写法,或者 decorator
- 组件的名字的首字母一定要大写
顶层API
最简单的React组件及其渲染
react.js
React.Children: Object
React.Component: ReactComponent(props, context, updater)
React.DOM: Object
React.PropTypes: Object
React.cloneElement: (element, props, children)
React.createClass: (spec)
React.createElement: (type, props, children)
React.createFactory: (type)
React.createMixin: (mixin)
React.isValidElement: (object)
Component API
this.context: Object
this.props: Object
this.refs: Object
this.state: Object
this.setState: Object
react-dom.js
ReactDOM.findDOMNode: findDOMNode(componentOrElement)
ReactDOM.render: ()
ReactDOM.unmountComponentAtNode: (container)
jsx语法
类似 xml 的语法,用来描述组件树
不用JSX,用React提供的API写的话
注释、命名、根元素个数、JSX 嵌入变量
React只有一个限制, 组件只能渲染单个根节点。如果你想要返回多个节点,它们必须被包含在同一个节点里。
styles
JSX SPREAD
可以用通过 {…obj} 来批量设置一个对象的键值对到组件的属性,注意顺序
属性名不能和 js 关键字冲突
例如:className
, readOnly
, htmlfor
数据流: state props propType
state && setState
用状态控制组件变化 可以把一个组件看做一个状态机, 每一次状态对应于组件的一个 ui
组件内部的状态,可以使用 state
props
通过 this.props 可以获取传递给该组件的属性值,还可以通过定义 getDefaultProps 来指定默认属性值(这是ES5的写法,ES6定义组件的默认props可以直接写props)
下面几个是props的常用API:
- this.props.children
- this.props.map
- this.props.filter
props是调用组件的时候传递进去的数据,一般用于组件树数据传递
propTypes
通过指定 propTypes 可以校验props属性值的类型,校验可提升开发者体验,用于约定统一的接口规范。
调用API定义组件
用 React.createClass或者React.Component 定义组件时允许传入相应的配置及组件API的使用,包括组件生命周期提供的一系列钩子函数。
- 组件初始定义
- getDefaultProps 得到默认属性对象,这个在ES6的时候不需要这样定义
- propTypes 属性检验规则
- mixins 组件间公用方法
- getDefaultProps 得到默认属性对象,这个在ES6的时候不需要这样定义
- 初次创建组件时调用
- getInitialState 得到初始状态对象
- render 返回组件树. 必须设置
- componentDidMount 渲染到 dom 树中是调用,只在客户端调用,可用于获取原生节点
- 组件的属性值改变时调用
- componentWillReceiveProps 属性改变调用
- shouldComponentUpdate 判断是否需要重新渲染
- render 返回组件树. 必须设置
- componentDidUpdate 渲染到 dom 树中是调用, 可用于获取原生节点
- 销毁组件
- componentWillUnmount 组件从 dom 销毁前调用
- 示例诠释组件全生命周期1234567891011121314151617181920212223242526272829303132333435363738394041424344454647import React, { Component } from 'react';class LifeCycle extends Component {Props = {value: '开始渲染'}componentWillReceiveProps(nextProps){console.log('componentWillReceiveProps');this.setState({value: nextProps.value});}shouldComponentUpdate(nextProps,nextState){console.log('shouldComponentUpdate');return true;}componentWillUpdate(nextProps,nextState){console.log('componentWillUpdate');}componentWillMount(){console.log('componentWillMount');}render() {console.log('render');return <span>{this.props.value}</span>}componentDidMount() {console.log('componentDidMount');}componentDidUpdate(prevProps,prevState) {console.log('componentDidUpdate');}componentWillUnmount(prevProps,prevState) {console.log('componentWillUnmount');}}export default LifeCycle;
调用组件并销毁组件示例
回顾组件的渲染过程
- 创建-》渲染-》销毁
- getDefaultProps()
- getInitialState()
- componentWillMount()
- render()
- componentDidMount()
- componentWillUnmount()
- 更新组件
- componentWillReceiveProps()
- shouldComponentUpdate()
- componentWillUpdate()
- render()
- componentDidUpdate()
使用ref对操作DOM
- ReactDOM.findDOMNode
- this.refs.xxx
获取DOM后可以方便结合现有非 react 类库的使用,通过 ref/refs 可以取得组件实例,进而取得原生节点,不过尽量通过 state/props 更新组件,不要使用该功能去更新组件的DOM。
|
|
再看一个有趣的例子
事件event
可以通过设置原生 dom 组件的 onEventType 属性来监听 dom 事件,例如 onClick, onMouseDown,在加强组件内聚性的同时,避免了传统 html 的全局变量污染
注意:事件回调函数参数为标准化的事件对象,可以不用考虑 IE
8. 组件的组合
- 受限组件 && 非受限组件
受限组件示例:
非受限组件示例:
使用自定义的组件
1234567891011121314151617181920212223242526272829;import React, { Component } from 'react';class ComponentA extends Component {render() {return <a href='#'>我是组件A<br/></a>}}class ComponentB extends Component {render() {return <a href='#'>我是组件B</a>}}class SelfCreateComponent extends Component {render() {return (<i><ComponentA /><ComponentB /></i>);}}export default SelfCreateComponent;组合 CHILDREN
自定义组件中可以通过 this.props.children 访问自定义组件的子节点123456789101112131415161718192021222324252627282930;import React, { Component } from 'react';// 定义一个组件,通过React.Children 拿到组件里面的子元素class ListComponent extends Component {render(){return <ul>{React.Children.map( this.props.children, function(c){return <li>{c}</li>;})}</ul>}}class UseChildrenComponent extends Component {render(){return (<ListComponent><a href="#">Facebook</a><a href="#">Google</a><a href="#">SpaceX</a></ListComponent>)}}export default UseChildrenComponent;
form表单操作
- React表单组件和 html 的不同点
- value/checked 属性设置后,用户输入无效
- textarea 的值要设置在 value 属性
<Textarea name="description" value="This is a description." />
- select 的 value 属性可以是数组,不建议使用 option 的 selected 属性
<select multiple={true} value={['B', 'C']}> <option value="A">Apple</option> <option value="B">Banana</option> <option value="C">Cranberry</option> </select>
- input/textarea 的 onChange 用户每次输入都会触发(即使不失去焦点)
- radio/checkbox/option 点击后触发 onChange
- 综合表达组件示例
定义复选框组件Checkboxes12345678910111213141516import React, { Component } from 'react';class Checkboxes extends Component {render(){return <span>A<input onChange={this.props.handleCheck} name="goodCheckbox" type="checkbox" value="A"/>B<input onChange={this.props.handleCheck} name="goodCheckbox" type="checkbox" value="B" />C<input onChange={this.props.handleCheck} name="goodCheckbox" type="checkbox" value="C" /></span>}}export default Checkboxes;
定义单选框按钮组RadioButtons
FormApp组件集成两个组件并处理表单逻辑
10. mixin共享
mixin 是一个普通对象,通过 mixin 可以在不同组件间共享代码,使你的React程序变得更为可重用。
注意,ES6语法不支持mixin写法,而是可以通过decorator去实现代码共享,这里使用ES5语法做示例说明。
那么,接下来,我们用high-order component的方式来实现mixin:
---此文摘抄自学习珠峰郭永峰老师的React