react and redux(一)props和state

  • 安装
  • 示例
  • 总结

安装

  1. 安装好node.js和npm之后,命令行执行下面的命令:
npm install --global create-react-app
  1. 创建应用目录:
create-react-app first_react_app //first_react_app为应用名
  1. 在应用目录下:
npm start

启动之后浏览器会自动打开页面:http://localhost:3000/

应用的入口是src/index.js文件。发现渲染的组件是App,对应App.js文件中的组件。

示例

修改index.js如下:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import ClickCounter from './ClickCounter';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<ClickCounter />, document.getElementById('root'));
registerServiceWorker();

这样应用启动后加载的组件就是ClickCounter这个组件了,这个组件实现对应的ClickCounter.js文件如下:

import React,{Component} from 'react';
export default class ClickCounter extends Component{

    constructor(props){
        super(props);
        this.onClickButton = this.onClickButton.bind(this);
        this.state={count:0};
    }

    onClickButton(){
        this.setState({count:this.state.count+1});
    }

    render(){
        return (
            <div>
                <button onClick={this.onClickButton}>Click Me</button>
                <div>
                    Click Count:{this.state.count}
                </div>
            </div>
        );
    }
}

启动应用后,点击按钮,计数器自动加1。

下面是上面这个例子的加强版,实现自定义组件的相互嵌套。
父组件的代码如下:

import React,{Component} from 'react';
import Counter from './Counter';
export default class ControlPanel extends Component{
    render(){
        return(
            <div>
                <Counter caption="First" initValue={0}/>
                <Counter caption="Second" initValue={10}/>
                <Counter caption="Third" initValue={20}/>
            </div>
        )
    }
}

其中父组件内部调用了子组件Counter,并传给它两个prop,一个是caption,一个是initValue,其中由于catpion属性是字符串,可以被JSX语法直接识别,而initValue是数字,由于JSX语法中,非字符串的属性赋值时需要用{}的形式才能正确赋值,所以以{0}这种方式。
下面是Counter组件的代码:

import React,{Component} from 'react';
export default class Counter extends Component{
    constructor(props){
        super(props);

        this.onClickIncrementButton=this.onClickIncrementButton.bind(this);
        this.onClickDecrementButton=this.onClickDecrementButton.bind(this);

        this.state = {
            count: props.initValue || 0
        }
    }

    onClickIncrementButton(){
        this.setState({count:this.state.count+1});
    }

    onClickDecrementButton(){
        this.setState({count:this.state.count-1});
    }

    render(){
        const {caption} = this.props;
        return (
            <div>
                <button  onClick={this.onClickIncrementButton}>+</button>
                <button  onClick={this.onClickDecrementButton}>-</button>
                <span>{caption} count:{this.state.count}</span>
            </div>
        );
    }
}

由上可见,传入的属性cation只是用于显示,initValue只是用于设置组件内部state的初值,然后又加了可以给count这个内部state加1和减1的按钮,以及最终将count这个state显示。

总结

  1. 本次的例子大致讲解了props和state的使用范围。props适用于组件外向组件内传参,而state只是在组件内部使用。
  2. 组件内修改state的值不能直接使用this.state.count=this.state.count+1;这种方式,因为这种方式只是野蛮地修改了state,却没有驱动组件进行重新渲染,所以并没有变化;而使用this.setState()函数首先改变this.state的值,然后驱动组件经历更新过程,界面上才会变化。
  3. 组件的构造函数中为什么要加上这两句话?
this.onClickIncrementButton=this.onClickIncrementButton.bind(this);
this.onClickDecrementButton=this.onClickDecrementButton.bind(this);

答:在ES6的语法中,类的每个成员函数在执行时的this并不是和类实例自动绑定的。而在构造函数中,this就是当前组件实例,所以为了将来在成员函数内部使用方便,在构造函数中将这个实例的特定函数绑定this为当前实例。这两条语句的作用,就是通过bind方法让当前实例中两个函数被调用时,函数内部的this始终指向当前组件实例。

猜你喜欢

转载自blog.csdn.net/u013985662/article/details/78009545