React 组件状态

组件状态是什么?
大多数组件只拥有属性和可渲染性。然而,它还可以提供状态这个特性,状态被用来存储组件在某段时间内状态改变的信息。用户事件或系统事件会导致一些典型的状态改变。(比如,对用户输入的回应,服务器的请求, 生命周期函数).
React 文档是这样解释 state 的:
组件事件处理中用到的数据发生改变时会触发 UI 更新。在现实的 app 中,这个数据趋向于很小,并且被 JSON 化。构建一个有状态的组件的时候,要想办法用最少的属性来代表这个状态的可能性,然后把这些属性存储在 this.state
中。你会发现以这种方式考虑而书写出来的 app 将是一个最正确的 app,因为给 state 添加过多的数据或已计算出的数据意味着你需要明确地保持 UI 状态和这些数据同步,而不是依赖 React 计算给你(也就是不能充分利用 React 的 state 机制了)。

关于 React 组件的 state,你需要记住以下几点:
1、如果一个组件有状态,那么它的默认状态是通过 getInitialState()
来提供的;
2、状态改变指得就是你会如何开启一个组件和它的子子孙孙组件的重渲染;
3、可以通过 this.setState()
去设置一个新 state 来告知组件 state 的改变;
4、状态改变会将新数据和该 state 里原来保存的老数据合并在一起;
5、状态改变时组件内部会进行重新渲染。不需要你再次调用 this.render()
;
6、state 对象只存储渲染 UI 需要的最少的数据。不要往 state 对象里放已计算的数据,别的 React 组件,或者 props.
State 如何进行工作
组件 state 工作是这样的:先给组件设置一个默认状态,再获取当前状态,最后更新这个状态。
在下面的代码示例中,我创建了一个组件 <MoodComponent />
,它示范了 getInitialState
,this.state.[STATE]
和 this.setState()
是如何使用的。如果你在浏览器上点击这个组件,它会在提供的这些状态中循环。从代码中可以看出,这个组件有 3 个潜在状态和 UI 绑定在一起,至于呈现哪一种状态则取决于用户的点击。
var MoodComponent = React.createClass({ getInitialState: function() { return {mood: ':|'}; }, changeMood:function(event,a){ const moods = [':)',':|',':(']; const current = moods.indexOf(event.target.textContent); this.setState({mood: current === 2 ? moods[0] : moods[current+1]}); }, render: function() { return ( <span style={{fontSize:'60',border:'1px solid #333',cursor:'pointer'}} onClick={this.changeMood}> {this.state.mood} </span> ) }});ReactDOM.render(< MoodComponent / >, app);
可以看到 <MoodComponent />
有一个初始状态 ‘:|' ,它是通过 getInitialState: function() {return {mood: ‘:|'};}
设置的,组件第一次渲染的时候, {this.state.mood}
写的就是它。
为了改变 state,添加了一个事件监听;在这个示例中,<span>
节点添加了点击事件(onClick
),它会调用 changeMood
函数。在这个函数里,我基于当前的 mood/state ,使用 this.setState()
去循环出下一个 mood。在 state 更新后,组件自己会进行重新渲染, UI 发生改变。
State vs. Props
state
和 props
的共同之处:
1、都是简单的 JS 对象;
2、都有默认值;
3、都能通过 this.props
或 this.state
来读取,而且都不能用这种方式来设置值;使用 this.
时,它们都是只读的。
不同之处:
Props:
1、Props 是由它的祖上传到当前组件中的,祖上或者是父母,也可能是 React 最初渲染时的初始域;
2、Props 作为配置值传给组件。类似把参数传给函数;
3、组件接收的时候, Props 是不可变的。也就是说,在组件内部,不能改变传递给组件的 Props。
State:
1、State 是和 UI 绑定的某一时间点上的序列化数据代表;
2、State 都是从默认值开始,然后通过使用 setState()
进行内部改变;
3、State 只能被含有状态特性的组件修改。从这点上来看它是私有的;
4、不能更改子组件的状态。组件永远不会共享可变的状态;
5、State 只包含代表 UI 状态的最少量的数据。不包含已计算的数据,其他的 React 组件和从 props 复制来的数据;
6、如果可能的话,尽量避免使用 State 。无状态组件是理想化的,有状态组件增加了复杂度。React 文档这样建议:创建无状态组件的一般模式只是渲染数据,有状态组件高于它一个层级,通过 props 传递状态给它的子组件。有状态组件压缩了所有的交互逻辑,而无状态组件以一种声明方式来关注渲染的数据。
创建有状态函数组件
当一个组件只有孤单的 props
,没有 state
时,组件可以被写成纯函数,从而避免了创建组件实例的需要。在下面代码示例中,MyComponent
是一个函数,返回从 React.createElement()
得到的结果。

不用 JSX 的话,上面的代码会是这个样子:
var MyComponent = function MyComponent(props) { return React.createElement( "div", null, "Hello ", props.name );};ReactDOM.render(React.createElement(MyComponent, { name: "doug" }), app);

构建一个没有调用 React.createClass()
的 React 组件被称为无状态函数组件。
无状态函数组件不能被传递组件选项(render
, componentWillUnmount
等等)。然而,.propTypes
和 .defaultProps
在函数中可以被作为属性设置。
下面代码示范了如何在无状态函数组件中设置 .propTypes
和 .defaultProps

本节笔记
制作组件时,尽最大可能将你的组件制作成无状态的。

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

推荐阅读更多精彩内容