React.js:组件,事件,state,props

我们来写上次提到的组件,计数器。

组件

/src 下新建一个文件 Counter.js

import React, {Component} from 'react'
import './Counter.css' 

class Counter extends Component{
    render(){
        return(
            <div>
                <div className="counter">
                <input type="button" className="counterLeftButton" value="-" />
                <input type="text" value="0" />
                <input type="button" className="counterRightButton" value="+" />
            </div>
        )
    }
}

export default Counter
  1. 这里没有用到元素渲染,就不用引入ReactDOM 了。我们统一在 index.js 中渲染。这里还引入了一个对应的 CSS 文件,稍微修饰一下。
  2. 注意 render 方法只能返回一个JSX元素,有多个并列元素时,外层用 <div> 包一下就好。
  3. 最后一行用于导出类,这样在别的 js 文件中就可以引入了。如果不想写最后一行,可以在定义的时候直接这样写:
export default class Counter extends Component

嵌套

接下里,让这个 Counter 在页面中显示出来,两个办法:

  1. public/index.html 中加入一个 HTML 元素,在 src/index.js 中引入 Counter 并渲染到上面的 HTML元素中。
<div id="counter"></div>
...
import Counter from './Counter'
...
ReactDOM.render(<Counter />, document.getElementById('counter'));
...
  1. 直接把 <Counter /> 嵌套到之前 hello 所在的JSX元素中:
...
import Counter from './Counter'
...
render(){
    return(
        <div>
            hello
            <Counter />
        </div>
    )
}

emmm...就这样吧。

当然如果你愿意,多放几个也是没问题的。

...
render(){
    const counters = []
    for(var i = 0; i < 5; i++){
        counters.push(<Counter/>)
    }
    return(
        <div>
            {counters}
        </div>
    )
}
...

事件

到现在为止,按钮点了没反应,也不能自己输入数字。是的,React.js 中无法直接更改 input 元素的值。不过使用 React.js 提供的监听事件机制,很容易就能做到,把 onChangeonClick 等等, 像是 onXxx 这种事件当做属性,添加上对应的处理方法,设置到 JSX 元素上就可以了。
但是有一点,React.js 会直接调用这个方法,并没有通过对象调用,所以,如果要在方法中用 this 关键字,需要自己绑定 bind

<input type="text" value="0" onChange={this.handleInputValueChange.bind(this)}/>

Counter 类中加上 handleInputValueChange 方法

handleInputValueChange(event){
    console.log(event.target.value)
}

然后,去修改 input 中的值,你就能在控制台看到了……
摔,要直接在页面上让我看到啊混蛋,能不能给点力啊。

state

emmm...

看起来我们没办法直接在函数里访问 JSX 元素啊,不过,要是把 inputvalue 值设置为变量,在函数里修改再体现在页面上不就可以了。等同于,我们直接改了元素的 数据状态React.js 为组件提供了 state 机制,我们在里面存放一个变量 count 就好。

constructor () {
    super()
    this.state = { count: 0 }
}

handleInputValueChange(event){
    this.state.count = event.target.value
}

...
<input type="text" value={this.state.count} ... />
...

你会发现,还是不行…… emmm ...
自己直接修改 this.state 中的数据, React.js 不会给渲染的,这里需要调用 setState

this.setState({count: event.target.value});

同样的,给两个 button 加上 onClick 事件:

<input type="button"  value="-" onClick={this.handleCountDecrease.bind(this)}/>
...
<input type="button"  value="+" onClick={this.handleCountIncrease.bind(this)}/>

实现这两个方法,加上数据验证什么的,到现在为止,看起来似乎还不错。

props

但是,这个组件除了在购物车界面中使用,还有可能用在其他的地方,并且或许有另外的文本要求,这里使用了“-”,“+”,或许别的需求里需要其他字符,像是“<” 和 “>”,so,到此为止它的扩展性还是不够,如果可以在使用的时候直接在外部设置某些属性,就更好了。比如这样用:

<Counter leftButtonText="<" rightButtonText=">" />

我们在组件 Counter 中提前设置好默认值,通过 this.props.参数名 使用:

static defaultProps = {
    leftButtonText: "-",
    rightButtonText: "+"
}
...
<input type="button" value={this.props.leftButtonText} .../>
<input type="text" .../>
<input type="button" value={this.props.rightButtonText} .../>
...

ta-da


不过传进来的 props 不能在组件内部修改,需要改变的时候,可以通过父组件重新渲染。当然,如果需要,直接传函数进来也是可以的。在 index.js 中定义函数并传入:

handleCounterClick(event){
    console.log("click handled by props")
}

render(){
    return(
        <Counter handleClick={this.handleCounterClick}/>
    )
}

组件 Counter.js 中直接使用就好:

<div className="counter" onClick={this.props.handleClick}>...</div>

这下勉强算得上是一个组件吧。任何需要它出现的地方,直接使用 <Counter />就OK了。

今天就到这里了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,576评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,515评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,017评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,626评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,625评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,255评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,825评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,729评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,271评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,363评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,498评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,183评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,867评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,338评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,458评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,906评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,507评论 2 359

推荐阅读更多精彩内容

  • 深入JSX date:20170412笔记原文其实JSX是React.createElement(componen...
    gaoer1938阅读 8,073评论 2 35
  • 3. JSX JSX是对JavaScript语言的一个扩展语法, 用于生产React“元素”,建议在描述UI的时候...
    pixels阅读 2,839评论 0 24
  • 本笔记基于React官方文档,当前React版本号为15.4.0。 1. 安装 1.1 尝试 开始之前可以先去co...
    Awey阅读 7,726评论 14 128
  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 2,842评论 1 18
  • 文/孤鸟差鱼 现在的我 活的糟糕的样子 都怕把鬼吓着
    孤鸟差鱼阅读 193评论 0 2