react and redux(一)props和state

来源:互联网 发布:大量收购淘宝店铺 编辑:程序博客网 时间:2024/06/05 17:52
  • 安装
  • 示例
  • 总结

安装

  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始终指向当前组件实例。

原创粉丝点击