状态、属性、组件 API、组件的生命周期
当 react 的状态改变时,自动执行 this.render() 方法更新组件
ES6 写 React 的时候,事件里不会自动绑定 this,需要自己绑定,或者直接在 constructor 里写方法
- constructor(props) {
- super(props);
- this.state = {
- liked: false
- };
- this.handleClick = (e) = >{
- this.setState({
- liked: !this.state.liked
- });
- };
- }
状态
- import React from 'react';
- class LikeButton extends React.Component {
- // es6用constructor代替getInitialState
- constructor(props) {
- super(props);
- this.state = {
- liked: false
- }
- }
- handleClick(e) {
- this.setState({
- liked: !this.state.liked
- })
- }
- render() {
- let text = this.state.liked ? '喜欢': '不喜欢';
- return (
- this.handleClick.bind(this)
- } > 你喜欢红茶吗? {
- text
- }
- )
- }
- }
- export
- default LikeButton;
props
HelloMessage.jsx
- import React from 'react';
- class HelloMessage extends React.Component {
- render() {
- return (
- Hello, {
- this.props.name
- }
- )
- }
- }
- export
- default HelloMessage;
main.js
- import React from 'react';
- import ReactDOM from 'react-dom';
- import HelloMessage from './component/HelloMessage';
- const app = document.getElementById('app');
- ReactDOM.render("Runoob"/>, app);
props 验证
可以保证应用组件被正确使用
React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。当 props 传入无效数据时,JavaScript 控制台会抛出错误。
- import React from 'react';
- class HelloMessage extends React.Component {
- render() {
- return (
- Hello, {
- this.props.name
- }
- )
- }
- }
- // getDefaultProps要写在外部
- HelloMessage.defaultProps = {
- name: 'this is default name'
- };
- HelloMessage.propTypes = {
- name: React.PropTypes.string.isRequired
- };
- export
- default HelloMessage;
更多验证器
- React.createClass({
- propTypes: {
- // 可以声明 prop 为指定的 JS 基本数据类型,默认情况,这些数据是可选的
- optionalArray: React.PropTypes.array,
- optionalBool: React.PropTypes.bool,
- optionalFunc: React.PropTypes.func,
- optionalNumber: React.PropTypes.number,
- optionalObject: React.PropTypes.object,
- optionalString: React.PropTypes.string,
- // 可以被渲染的对象 numbers, strings, elements 或 array
- optionalNode: React.PropTypes.node,
- // React 元素
- optionalElement: React.PropTypes.element,
- // 用 JS 的 instanceof 操作符声明 prop 为类的实例。
- optionalMessage: React.PropTypes.instanceOf(Message),
- // 用 enum 来限制 prop 只接受指定的值。
- 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),
- // 特定 shape 参数的对象
- optionalObjectWithShape: React.PropTypes.shape({
- color: React.PropTypes.string,
- fontSize: React.PropTypes.number
- }),
- // 任意类型加上 `isRequired` 来使 prop 不可空。
- requiredFunc: React.PropTypes.func.isRequired,
- // 不可空的任意类型
- requiredAny: React.PropTypes.any.isRequired,
- // 自定义验证器。如果验证失败需要返回一个 Error 对象。不要直接使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。
- customProp: function(props, propName, componentName) {
- if (!/matchme/.test(props[propName])) {
- return new Error('Validation failed!');
- }
- }
- },
- /* ... */
- });
React 组件 API
setState 设置状态
replaceState 替换状态
setProps 设置属性
replaceProps 替换属性
forceUpdate 强制更新
findDOMNode 获取 DOM 节点, 查找真实 DOM
React.findDOMNode() 只在 mounted 组件中调用,如果在组件的 render() 方法中调用 React.findDOMNode() 就会抛出异常。
React 组件的生命周期
组件生命周期的三个状态
Mounting: 已插入真实 DOM
Updating: 正在被重新渲染
Unmounting: 已移除真实 DOM
生命周期方法
componentWillMount 在渲染前调用,在客户端也在服务端
componentDidMount 在第一次渲染后调用,只在客户端。
之后组件已经生成了对应的 DOM 结构,可以通过 this.getDOMNode() 来进行访问。
如果你想和其他 JavaScript 框架一起使用,可以在这个方法中调用 setTimeout, setInterval 或者发送 AJAX 请求等操作 (防止异部操作阻塞 UI)。
componentWillReceiveProps 在初始化 render 时不会被调用,当组件接收到一个新的 prop 时被调用
shouldComponentUpdate 返回一个布尔值。当确认不需要更新组件时使用。在组件接收到新的 state 或新的 props 时被调用。在初始化时或使用 forceUpdate 时不被调用
componentWillUpdate 初始化不会调用。组件接收到新的 state 或者 props 但还没有 render 时被调用
componentDidUpdate 初始化不会调用。组件完成更新后立即调用。
componentWillUnmount 组件从 DOM 中移除的时候立刻被调用。
用 state 判断是否已经插入真实 DOM
- componentWillMount() {
- this.mounted = false;
- }
- componentDidMount() {
- this.mounted = true;
- }
需求:写一个实例,在组件加载以后,通过 componentDidMount 设置一个定时器,改变组件的透明度并重新渲染
HelloMessage.jsx
- import React from 'react';
- class HelloMessage extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- opacity: 1.0
- };
- }
- componentDidMount() {
- this.timer = setInterval(() = >{
- let opacity = this.state.opacity;
- opacity -= 0.05;
- if (opacity <= 0.1) {
- opacity = 1.0;
- }
- this.setState({
- opacity: opacity
- });
- },
- 100);
- }
- render() {
- let myStyle = {
- fontFamily: 'microsoft yahei',
- width: '100%',
- height: '100px',
- background: 'red',
- opacity: this.state.opacity
- };
- return (
- Hello, {
- this.props.name
- } {
- this.state.opacity
- }
- )
- }
- }
- // getDefaultProps要写在外部
- HelloMessage.defaultProps = {
- name: 'this is default name'
- };
- HelloMessage.propTypes = {
- name: React.PropTypes.string.isRequired
- };
- export
- default HelloMessage;
另一个实例,体现 react 的生命周期
- import React from 'react';
- class Content extends React.Component {
- componentWillMount() {
- console.log('组件将被插入到真实DOM');
- }
- componentDidMount() {
- console.log('已经插入真实DOM');
- }
- componentWillReceiveProps(newProps) {
- console.log('组件将要接收属性,新属性是:');
- console.log(newProps);
- }
- shouldComponentUpdate(newProps, newState) {
- return true;
- }
- componentWillUpdate(nextProps, nextState) {
- console.log('组件将要更新,下一个属性:' + nextProps + ',下一个状态:' + nextState);
- console.log(nextProps);
- }
- componentDidUpdate(prevProps, prevState) {
- console.log('组件已更新,上一个属性:' + prevProps + ',上一个状态:' + prevState);
- console.log(prevProps);
- }
- componentWillUnmount() {
- console.log('已经移除真实DOM');
- }
- render() {
- return (
- 次数: {
- this.props.myNum
- }
- )
- }
- }
- class Increment extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- data: 0
- };
- }
- setNewNumber() {
- this.setState({
- data: this.state.data + 1
- });
- }
- render() {
- return (
- this.setNewNumber.bind(this)
- } > Increment this.state.data
- }
- />
- )
- }
- }
- export default Increment;/
未完待续 ... ...
来源: