本篇将介绍 React 组件的API,其中主要的几个API我们在第一篇的时候便已介绍过,这里可以做个温故知新。

本篇的代码你也可以在我的Github上获取到。

setState

参数: nextState(object), [callback(function)]

设置 nextState 的某个键(属性)(别忘了我们可以在 shouldComponentUpdate 方法中获取到 nextState 的值来跟当前的 this.state 进行对比),然后下一次 EventLoop 时 this.state 的对应键就会被更新为该设定的值。

通常我们如果希望在某个事件或某个回调中来重新渲染组件(触发UI更新内容),setState 是一个最常用的触发方法,因为我们把UI内容跟state状态直接(或者通过某些条件)绑定在了一起,一旦state发生改变并触动了绑定的逻辑,那么UI内容自然也会跟着变动:

    var Component1 = React.createClass({
getInitialState: function() {
return {
isClick: !1
}
},
componentDidUpdate: function(){
console.log('componentDidUpdate')
},
clickCb: function() {
this.setState({
isClick : !0
}, function(){
console.log(this.state.isClick)
})
},
render: function() {
return (<div onClick={this.clickCb}>
isClick:{this.state.isClick ? 'yes' : 'nope'}
</div>)
}
});
var div = document.getElementById('a');
React.render(
<Component1 />, div
);

如上我们通过 state.isClick 来决定div内要显示的内容,而我们点击div时会改变 state.isClick 的状态,从而触发绑定条件更改了div中的内容。

注意这段代码里我们使用了 componentDidUpdate 方法,如第二篇文章中所介绍的,它在组件重新渲染后会立即触发。我们点击 div 之后发现打印顺序是这样的:

即我们在 setState 方法中所定义的回调,它是在组件重新渲染之后才执行的,而不是在我们变更了 nextState 的值之后就立即触发。

replaceState

参数: nextState(object), [callback(function)]

类似于 setState(),但是删除之前所有已存在的 state 键(key),这些键都不在 nextState 中。

这句话怎么理解呢?我们看这个例子:

    var Component1 = React.createClass({
getInitialState: function() {
return {
isClick: !1,
abc: 1 //注意这里我们初始化了一个 state.abc
}
},
clickCb: function() {
this.replaceState({
isClick : !0
}, function(){
console.log(this.state)
})
},
render: function() {
return (<div onClick={this.clickCb}>
isClick:{this.state.isClick ? 'yes' : 'nope'}
</div>)
}
});
var div = document.getElementById('a');
React.render(
<Component1 />, div
);

注意我们在 getInitialState 里还额外定义了一个 abc 的 state 属性,但在 replaceState 后再试着打印 this.state,会发现这个 state.abc 已经被删除了(如果换成 setState 则不会被删除)

所以顾名思义,replaceState 就是一个彻底更换掉 state 的方法,寻常使用的时候需要小心使用,避免删掉一些重要的state属性。

forceUpdate

参数: [callback(function)]

顾名思义就是在任何调用的时刻强制渲染组件,例如即使 shouldComponentUpdate 返回了false:

    var Component1 = React.createClass({
shouldComponentUpdate: function(nextProps, nextState){
console.log( this.state, nextState );
this.forceUpdate(function(){
console.log('强制渲染完成')
}); //强制渲染,去掉这行则不会渲染
return false;
},
componentDidUpdate: function(){
console.log('componentDidUpdate')
},
getInitialState: function() {
return {
isClick: !1
}
},
clickCb: function() {
this.setState({
isClick : !this.state.isClick
})
},
render: function() {
return (<div onClick={this.clickCb}>
isClick:{this.state.isClick ? 'yes' : 'nope'}
</div>)
}
});
var div = document.getElementById('a');
var c1 = React.render(
<Component1 />, div
);

注意该方法的回调,也是在重新渲染之后才执行的。

另一个使用 forceUpdate 的场景可以是,我们不以 props 或 state 来作为触发渲染的条件,例如使用了一个变量来作为UI内容,在该变量的值改变了且我们希望触发渲染时,可以使用该方法,当然这种形式是不推荐的。

getDOMNode()

返回组件/ReactElement挂载到页面上所对应的DOM元素:

    var Component1 = React.createClass({
getInitialState: function() {
return {
isClick: !1
}
},
clickCb: function() {
this.setState({
isClick : !0
}, function(){
console.log(this.state.isClick)
})
},
render: function() {
return (<div onClick={this.clickCb}>
isClick:{this.state.isClick ? 'yes' : 'nope'}
</div>)
}
});
var div = document.getElementById('a');
var c = React.render(
<Component1 />, div
);
console.log(c.getDOMNode())

打印结果:

另外,若 render 返回 null 或者 false 的时候,this.getDOMNode() 将返回 null。

isMounted()

返回一个 Boolean 值,如果组件挂载到了 DOM 中,isMounted() 返回 true。

其适用于异步请求的情景下:

    var Component1 = React.createClass({
getInitialState: function() {
return {
content: 'hello'
}
},
componentWillMount: function () {
doSomething(props).then(function (content) {
if (this.isMounted()) {
this.setState({content: content});
}
}.bind(this));
},
render: function() {
if(this.state.isClick){
return (<div>
content:{this.state.content}
</div>)
} else {
return false;
}
}
});
var div = document.getElementById('a');
var c = React.render(
<Component1 />, div
);

如上代码,我们在 componentWillMount 的时候执行一个异步请求 doSomething,在其获取到服务器数据的时候修改 state 的值,前提是组件已经挂载到页面上。

如果该异步请求完成得很快,我们获取到新content时候组件可能还在处于挂载中(mounting)的过程,那么 state 则保持不变(因为此时 isMounted() 将返回false )。

setProps

参数: nextProps(object), [callback(function)]

跟 setState 类似,不过修改的是 props 罢了:

    var Component1 = React.createClass({
clickCb: function() {
this.setProps({
name : 'cnBlog'
}, function(){
console.log(this.props)
})
},
render: function() {
return (<div onClick={this.clickCb}>
{this.props.sayhi || 'www.'}
{this.props.name || 'nothing'}
</div>)
}
});
var div = document.getElementById('a');
React.render(
<Component1 name="VaJoy" sayhi="Hello " />, div
);

replaceProps

参数: nextProps(object), [callback(function)]

类似于 setProps,会替换掉现有的 props 的键,我们依旧使用上一段代码,不过把 setProps 换成 replaceProps:

    var Component1 = React.createClass({
clickCb: function() {
this.replaceProps({
name : 'cnBlog'
}, function(){
console.log(this.props)
})
},
render: function() {
return (<div onClick={this.clickCb}>
{this.props.sayhi || 'www.'}
{this.props.name || 'nothing'}
</div>)
}
});
var div = document.getElementById('a');
React.render(
<Component1 name="VaJoy" sayhi="Hello " />, div
);

我们这时再点击组件,会发现 props.sayHi 已被删除了:

Refs

事实上这个不属于组件的方法,但也是在组件中常用的一个小技巧,故在这里做介绍。

我们在前面提到,可以使用 ReactClass.getDOMNode() 的方法来获取到组件渲染在页面上的DOM节点,但是如果我们希望获取到的,是组件中的某个DOM元素呢?

这时候我们可以使用定义 refs 的形式,来方便我们获取对应的元素:

    var Component1 = React.createClass({
clickCb: function(e) {
if(e.target === this.refs.li2.getDOMNode()){
alert('你点到第二个LI了')
}
},
render: function() {
return (<ul onClick={this.clickCb}>
<li>1</li>
<li ref="li2">2</li>
<li>3</li>
</ul>)
}
});
var div = document.getElementById('a');
React.render(
<Component1 />, div
);

如上我们给组件中的第二个<li>绑定了一个 ref 属性,值为“li2”,这意味着我们可以在组件中以 this.refs.li2 的形式来获取到该ReactElement。

然后绑定点击事件,在点击的时候判断被点击的 li 元素是否等于 this.refs.li2.getDOMNode(),是的话则弹出alert。

官方也给出了一个实用的demo:

  var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
// Clear the input
this.setState({userInput: ''}, function() {
// 组件重绘后会立即执行这句代码:
this.refs.theInput.getDOMNode().focus(); // input成功聚焦(focus)
});
},
render: function() {
return (
<div>
<div onClick={this.clearAndFocusInput}>
Click to Focus and Reset
</div>
<input
ref="theInput" //我们可以在组件里以 this.refs.theInput 获取到它
value={this.state.userInput}
onChange={this.handleChange}
/>
</div>
);
}
});

到此位置我们便基本入门了 React 的大部分主要的API,后续我们将以项目实践的形式来进一步学习React。

共勉~!

ReactJS入门(四)—— 组件API的更多相关文章

  1. ReactJS入门3:组件的生命周期

    本文主要介绍组件的生命周期. 组建的生命周期主要分为3个:Mounting.Updating.Unmounting. 1. Mounting:组件被加载到DOM     在本阶段,主要有三个方法: 1 ...

  2. ReactJS入门2:组件状态

    React组件可以简单看做是包含props和states的函数. 上一节总结了创建新组建和数据属性的传递.本节主要讲解组件的状态. React认为UI是不同状态的展现.在React中,开发者只需更新组 ...

  3. reactjs入门到实战(六)---- ReactJS组件API详解

    全局的api 1.React.createClass 创建一个组件类,并作出定义.组件实现了 render() 方法,该方法返回一个子级.该子级可能包含很深的子级结构.组件与标准原型类的不同之处在于, ...

  4. Spring Boot入门(四):开发Web Api接口常用注解总结

    本系列博客记录自己学习Spring Boot的历程,如帮助到你,不胜荣幸,如有错误,欢迎指正! 在程序员的日常工作中,Web开发应该是占比很重的一部分,至少我工作以来,开发的系统基本都是Web端访问的 ...

  5. 微信小程序入门与实战 常用组件API开发技巧项目实战*全

    第1章 什么是微信小程序? 第2章 小程序环境搭建与开发工具介绍 第3章 从一个简单的“欢迎“页面开始小程序之旅 第4章 第二个页面:新闻阅读列表 第5章 小程序的模板化与模块化 第6章 构建新闻详情 ...

  6. ReactJS入门(三)—— 顶层API

    本文基本跟着官方文档把API都走一遍,但会有实例来解释应该怎么用,木有比我更详细的API文档咯. React.createClass 参数:CONFIG(object) 创建一个ReactClass( ...

  7. 一看就懂的ReactJs入门教程-精华版

    现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领 ...

  8. ReactJs入门教程

    现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领 ...

  9. 一看就懂的ReactJs入门教程(精华版)

    一看就懂的ReactJs入门教程(精华版) 现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和 ...

  10. [转]ReactJS入门教程

    Refference From:http://www.cocoachina.com/webapp/20150721/12692.html 现在最热门的前端框架有AngularJS.React.Boot ...

随机推荐

  1. APP产品交互设计分析总结(不断更新中...)

    1.首页中的最下方的TAB和中部的TAB的区别 最下面的tab按钮应该是核心级模块级的大功能入口 中间的按钮应该是次核心级页面级的小功能入口 2.对于编辑是在单页内实现好还是跳转到新页面实现好 内容比 ...

  2. android include进来的组件 调用其子元素

    include标签包裹着一个可复用的布局: <include layout="@layout/footer_detail" android:id="@+id/foo ...

  3. Solr与MySQL查询性能对比

    本文简单对比下Solr与MySQL的查询性能速度. 测试数据量:10407608     Num Docs: 10407608 这里对MySQL的查询时间都包含了从MySQL Server获取数据的时 ...

  4. Servlet

    建议:对于javaEE,在如何学习jsp和servlet时,初学者往往是一头雾水.我当时就被jsp的各种标签.内置对象和servlet整的很惨.所以,学习方法变得特别特别重要:而且,随着技术的更新和发 ...

  5. Windows7 64位系统搭建Cocos2d-x-2.2.1最新版以及Android交叉编译环境(详细教程)

    Windows7 64位系统搭建Cocos2d-x-2.2.1最新版以及Android交叉编译环境(详细教程) 声明:本教程在参考了以下博文,并经过自己的摸索后实际操作得出,本教程系本人原创,由于升级 ...

  6. MachineKey 操作 之 应用集群中SSO应用生成MachineKey

    MachineKey介绍 MachineKey其用于对 Forms 身份验证 Cookie 数据和视图状态数据进行加密和解密,一般情况下IIS自动默认给网站或者每一个应用生成唯一的MachineKey ...

  7. git 用不同的邮箱配置不同的ssh

    首先,介绍一下配置背景: 1.有两个邮箱A@mail.com  , B@mail.com 2.两个git账号,一个公司gitlab上的A@mail ,另一个github上的B@mail 3. 目标:提 ...

  8. GIT版本管理工具

    原文:http://blog.csdn.net/ithomer/article/details/7527877 Git 是一个分布式版本控制工具,它的作者 Linus Torvalds 是这样给我们介 ...

  9. 代替jquery $.post 跨域提交数据的N种形式

    跨域的N种形式: 1.直接用jquery中$.getJSON进行跨域提交 优点:有返回值,可直接跨域: 缺点:数据量小: 提交方式:仅get (无$.postJSON) $.getJSON(" ...

  10. 关于CSV文件 Excel打开乱码问题的解决方案

    近日写java程序中,将数据输出到csv文件中,发现Excel打开之后,中文均为乱码 于是寻找解决方案,发现最简单的方式还是如此了 1. 将输出的csv文件用记事本打开 2. 另存为将文件编码格式改为 ...