[深入剖析React Native]React 初探
2016-09-07 16:34
507 查看
认识React
React是一个用于构建用户界面的JavaScript库。React主要用于构建UI,很多人认为React是MVC中的V,即视图。
React起源于Facebook的内部项目,用来架设Instagram的网站,并于2013年5月开源。
React拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和实用它。
React特点
声明式设计 - React**采用声明范式**,可以轻松描述应用。高效 - React通过对DOM的模拟,最大限度地减少与DOM的交互。
灵活 - React可以与已知的库或框架很好地配合。
JSX - JSX是JavaScript语法的扩展。React开发不一定适用JSX,但我们建议使用它。
组件 - 通过React构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
单向响应的数据流 - React 实现了单项的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。
基础知识
在学习React之前,需要具备一下基础知识:- HTML5
- CSS
- JavaScript
简单实例
<div id="example"></div> <script type="text/babel"> ReactDOM.render( <h1>Hello World!</h1> document.getElementById('example') ); </script>
React安装
使用库:
<script src="build/react.js"></script> <script src="build/react-dom.js"></script> <script src="https://unpkg.com/babel-core@5.8.38/browser.min.js"></script>
使用实例:
输出Hello, world!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="build/react.js"></script> <script src="build/react-dom.js"></script> <script src="https://unpkg.com/babel-core@5.8.38/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('example') );
</script>
</body>
</html>
实例解析:
实例中我们引入了三个库: react.js 、react-dom.js 和 browser.min.js:
- react.js - React 的核心库
- react-dom.js - 提供与 DOM 相关的功能
- browser.min.js - 用于将 JSX 语法转为 JavaScript 语法
ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('example') );
以上代码将一个 h1 标题,插入 id=”example” 节点中。
注意:如果我们需要使用 JSX,则 script标签的 type 属性需要设置为 text/babel
通过npm使用React
我们建议在 React 中使用 CommonJS 模块系统,比如 browserify 或 webpack,本教程使用 webpack。安装全局包
$ npm install babel -g $ npm install webpack -g $ npm install webpack-dev-server -g
创建根目录
创建一个根目录,名称为mazouriApp,再使用npm init初始化,生成package.json文件:添加依赖包及插件
因为我们要使用React,所以我们需要先安装它, –save命令用于将包添加至package.json文件npm install react --save npm install react-dom --save
同时我们也需要安装一些babel插件
npm install babel-core npm install babel-loader npm install babel-preset-react npm install babel-preset-es2015
创建文件
接下来我们创建一些必要的文件:touch index.html touch App.jsx touch main.js touch webpack.config.js
设置编译器、服务器、载入器
打开webpack.config.js 文件添加以下代码:var config = { entry: './main.js', outout: { path: './', filename: 'index.js', }, devServer: { inline: true, port: 7777 }, module: { loaders: [{ test: /\.jsx?$/, exclude: /node_moudules/, loader: 'babel-loader', query: { presets: ['es2015', 'react'] } }] } } module.exports = config;
entry: 指定打包的入口文件main.js
output: 配置打包结果,path定义了输出的文件夹,filename则定义了打包结果文件的名称
devServer: 设置服务器端口号为7777,端口号你可以自己设定
module: 定义了对模块的处理逻辑,这里可以用loaders定义一些列的加载器,以及一些正则。当需要加载的文件匹配test的正则时,就会调用后面的loader对文件进行处理,这正是webpack强大的原因
现在打开 package.json 文件,找到 “scripts” 中的 “test” “echo \”Error: no test specified\” && exit 1” 使用以下代码替换:
"start": "webpack-dev-server --hot"
替换后的 package.json 文件 内容如下:
{ "name": "mazouri-react-demo", "version": "1.0.0", "description": "我的react demo", "main": "index.js", "scripts": { "start": "webpack-dev-server --hot" }, "author": "", "license": "ISC", "dependencies": { "react": "^15.3.1", "react-dom": "^15.3.1" } }
现在我们可以使用 npm start 命令来启动服务。–hot 命令会在文件变化后重新载入,这样我们就不需要在代码修改后重新刷新浏览器就能看到变化。
index.html
设置 div id = “app” 为我们应用的根元素,并引入 index.js 脚本文件<!DOCTYPE html> <html> <head> <meta charset = "UTF-8"> <title>mazouri React demo</title> </head> <body> <div id = "app"></div> <script src = "index.js"></script> </body> </html>
App.jsx 和 main.js
这是第一个 react 组件,这个组件将输出 Hello World!!!。import React from 'react'; class App extends React.Component { render() { return ( <div> Hello World!!!<br /> 这是mazouri react app的一个demo </div> ); } } export default App;
我们需要引入组件并将其渲染到根元素 App 上,这样我们才可以在浏览器上看到它
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; ReactDOM.render(<App />, document.getElementById('app'))
如果想要组件可以在任何的应用中使用,需要在创建后使用 export 将其导出,在使用组件的文件使用 import 将其导入。
运行服务
完成以上配置后,我们即可运行该服务:$ npm start
JSX
React 使用JSX来代替常规的JavaScript。JSX是一个看起来很像XML的JavaScript语法扩展。
我们不需要一定使用JSX,但它有以下优点:
JSX执行更快,因为它在编译为JavaScript代码后进行了优化
它是类型安全的,在编译过程中就能发现错误
使用JSX编写模版更加简单快速
使用JSX
JSX看起来类似HTML,我们可以看下实例:ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('example') );
我们可以在上面代码中嵌套多个HTML标签,需要使用一个div元素包裹它,实例中的p元素添加了自定义属性data-myattribute,添加自定义属性需要使用data-前缀。
ReactDOM.render( <div> <h1>标题</h1> <h2>React初探</h2> <p data-myattribute = "somevalue">这是一个段落</p> </div> , document.getElementById('example') );
独立文件
你的React JSX 代码可以放在一个独立文件上,例如我们创建一个helloworld_react.js文件,代码如下:ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('example') );
然后在 HTML 文件中引入该 JS 文件:
<body> <div id="example"></div> <script type="text/babel" src="helloworld_react.js"></script> </body>
JavaScript 表达式
我们可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。实例如下:ReactDOM.render( <div> <h1>{1+1}</h1> </div> , document.getElementById('example') );
在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代。以下实例中如果变量 i 等于 1 浏览器将输出 true, 如果修改 i 的值,则会输出 false.
ReactDOM.render( <div> <h1>{i == 1 ? 'True!' : 'False'}</h1> </div> , document.getElementById('example') );
样式
React 推荐使用内联样式。我们可以使用 camelCase 语法来设置内联样式. React 会在指定元素数字后自动添加 px 。以下实例演示了为 h1 元素添加 myStyle 内联样式:var myStyle = { fontSize: 100, color: '#FF0000' }; ReactDOM.render( <h1 style = {myStyle}>菜鸟教程</h1>, document.getElementById('example') );
注释
注释需要写在花括号中,实例如下:ReactDOM.render( <div> <h1>React初探</h1> {/*注释...*/} </div>, document.getElementById('example') );
数组
JSX 允许在模板中插入数组,数组会自动展开所有成员:var arr = [ <h1>React初探</h1>, <h2>学习React技术!</h2>, ]; ReactDOM.render( <div>{arr}</div>, document.getElementById('example') );
HTML 标签 vs. React 组件
React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes)。要渲染 HTML 标签,只需在 JSX 里使用小写字母的标签名。
var myDivElement = <div className="foo" />; ReactDOM.render(myDivElement, document.getElementById('example'));
要渲染 React 组件,只需创建一个大写字母开头的本地变量。
var MyComponent = React.createClass({/*...*/}); var myElement = <MyComponent someProperty={true} />; ReactDOM.render(myElement, document.getElementById('example'));
React 的 JSX 使用大、小写的约定来区分本地组件的类和 HTML 标签。
注意:由于 JSX 就是 JavaScript,一些标识符像 class 和 for 不建议作为 XML 属性名。作为替代,React DOM 使用 className 和 htmlFor 来做对应的属性。
React 组件
这节我们讨论如何使用组件使得我们的应用更容易来管理。接下来我们封装一个输出”Hello world!”的组件,组件名为HelloMessage:
var HelloMessage = React.createClass({ render: function() { return <h1>Hello World!</h1>; } }); ReactDOM.render( <HelloMessage />, document.getElementById('example') );
实例解析:
React.createClass 方法用于生成一个组件类 HelloMessage。
实例组件类并输出信息。
注意,原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头,比如 HelloMessage 不能写成 helloMessage。除此之外还需要注意组件类只能包含一个顶层标签,否则也会报错。
如果我们需要向组件传递参数,可以使用 this.props 对象,实例如下:
var HelloMessage = React.createClass({ render: function() { return <h1>Hello {this.props.name}</h1>; } }); ReactDOM.render( <HelloMessage name="Runoob" />, document.getElementById('example') );
以上实例中 name 属性通过 this.props.name 来获取.
注意,在添加属性时, class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。
复合组件
我们可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。以下实例我们实现了输出网站名字和网址的组件:
var WebSite = React.createClass({ render: function() { return ( <div> <Name name={this.props.name} /> <Link site={this.props.site} /> </div> ); } }); var Name = React.createClass({ render: function() { return ( <h1>{this.props.name}</h1> ); } }); var Link = React.createClass({ render: function() { return ( <a href={this.props.site}> {this.props.site} </a> ); } }); React.render( <WebSite name="Geek马走日" site="https://github.com/mazouri" />, document.getElementById('example') );
实例中 WebSite 组件使用了 Name 和 Link 组件来输出对应的信息,也就是说 WebSite 拥有 Name 和 Link 的实例
React State(状态)
React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
以下实例中创建了 LikeButton 组件,getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。
var LikeButton = React.createClass({ getInitialState: function() { return {liked: false}; }, handleClick: function(event) { this.setState({liked: !this.state.liked}); }, render: function() { var text = this.state.liked ? '喜欢' : '不喜欢'; return ( <p onClick={this.handleClick}> 你<b>{text}</b>我。点我切换状态。 </p> ); } }); React.render( <LikeButton />, document.getElementById('example') );
React Props
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据使用 Props
以下实例演示了如何在组件中使用 props:var HelloMessage = React.createClass({ render: function() { return <h1>Hello {this.props.name}</h1>; } }); ReactDOM.render( <HelloMessage name="Runoob" />, document.getElementById('example') );
实例中 name 属性通过 this.props.name 来获取。
默认 Props
你可以通过 getDefaultProps() 方法为 props 设置默认值,实例如下:var HelloMessage = React.createClass({ getDefaultProps: function() { return { name: 'Runoob' }; }, render: function() { return <h1>Hello {this.props.name}</h1>; } }); ReactDOM.render( <HelloMessage />, document.getElementById('example') );
State 和 Props
以下实例演示了如何在应用中组合使用 state 和 props 。我们可以在父组件中设置 state, 并通过在子组件上使用 props 将其传递到子组件上。在 render 函数中, 我们设置 name 和 site 来获取父组件传递过来的数据var WebSite = React.createClass({ getInitialState: function() { return { name: "Geek马走日", site: "https://github.com/mazouri" }; }, render: function() { return ( <div> <Name name={this.state.name} /> <Link site={this.state.site} /> </div> ); } }); var Name = React.createClass({ render: function() { return ( <h1>{this.props.name}</h1> ); } }); var Link = React.createClass({ render: function() { return ( <a href={this.props.site}> {this.props.site} </a> ); } }); React.render( <WebSite />, document.getElementById('example') );
Props 验证
Props 验证使用 propTypes,它可以保证我们的应用组件被正确使用,React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。以下实例创建一个 Mytitle 组件,属性 title 是必须的且是字符串,如果是一个数字则会报错 :
var title = "React 初探"; // var title = 123; var MyTitle = React.createClass({ propTypes: { title: React.PropTypes.string.isRequired, }, render: function() { return <h1> {this.props.title} </h1>; } }); ReactDOM.render( <MyTitle title={title} />, document.getElementById('example') );
更多验证器说明如下:
React.createClass({ propTypes: { // 可以声明 prop 为指定的 JS 基本数据类型,默认情况,这些数据是可选的 optionalArray: React.PropTypes.array, optionalBool: React.PropTypes.bool, optionalFunc: React.PropTypes.func, optionalNumber: React.PropTypes.number, optionalObject: React.PropTypes.object, optionalString: React.PropTypes.string, // 可以被渲染的对象 numbers, strings, elements 或 array optionalNode: React.PropTypes.node, // React 元素 optionalElement: React.PropTypes.element, // 用 JS 的 instanceof 操作符声明 prop 为类的实例。 optionalMessage: React.PropTypes.instanceOf(Message), // 用 enum 来限制 prop 只接受指定的值。 optionalEnum: React.PropTypes.oneOf(['News', 'Photos']), // 可以是多个对象类型中的一个 optionalUnion: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.number, React.PropTypes.instanceOf(Message) ]), // 指定类型组成的数组 optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number), // 指定类型的属性构成的对象 optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number), // 特定 shape 参数的对象 optionalObjectWithShape: React.PropTypes.shape({ color: React.PropTypes.string, fontSize: React.PropTypes.number }), // 任意类型加上 `isRequired` 来使 prop 不可空。 requiredFunc: React.PropTypes.func.isRequired, // 不可空的任意类型 requiredAny: React.PropTypes.any.isRequired, // 自定义验证器。如果验证失败需要返回一个 Error 对象。不要直接使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。 customProp: function(props, propName, componentName) { if (!/matchme/.test(props[propName])) { return new Error('Validation failed!'); } } }, /* ... */ });
React 组件 API
这节我们将讨论 React 组件 API。我们将讲解以下7个方法:设置状态:setState
替换状态:replaceState
设置属性:setProps
替换属性:replaceProps
强制更新:forceUpdate
获取DOM节点:findDOMNode
判断组件挂载状态:isMounted
设置状态:setState
setState(object nextState[, function callback])
参数说明
- nextState,将要设置的新状态,该状态会和当前的state合并
- callback,可选参数,回调函数。该函数会在setState设置成功,且组件重新渲染后调用
callback,可选参数,回调函数。该函数会在setState设置成功,且组件重新渲染后调用
关于setState
不能在组件内部通过this.state修改状态,因为该状态会在调用setState()后被替换setState()并不会立即改变this.state,而是创建一个即将处理的state。setState()并不一定是同步的,为了提升性能React会批量执行state和DOM渲染。
setState()总是会触发一次组件重绘,除非在shouldComponentUpdate()中实现了一些条件渲染逻辑
实例
var Counter = React.createClass({ getInitialState: function () { return { clickCount: 0 }; }, handleClick: function () { this.setState(function(state) { return {clickCount: state.clickCount + 1}; }); }, render: function () { return (<h2 onClick={this.handleClick}>点我!点击次数为: {this.state.clickCount}</h2>); } }); ReactDOM.render( <Counter />, document.getElementById('message') );
实例中通过点击 h2 标签来使得点击计数器加 1
替换状态:replaceState
replaceState(object nextState[, function callback])
nextState,将要设置的新状态,该状态会替换当前的state
callback,可选参数,回调函数。该函数会在replaceState设置成功,且组件重新渲染后调用
replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除。
设置属性:setProps
setProps(object nextProps[, function callback])
nextProps,将要设置的新属性,该状态会和当前的props合并
callback,可选参数,回调函数。该函数会在setProps设置成功,且组件重新渲染后调用
设置组件属性,并重新渲染组件。
props相当于组件的数据流,它总是会从父组件向下传递至所有的子组件中。当和一个外部的JavaScript应用集成时,我们可能会需要向组件传递数据或通知React.render()组件需要重新渲染,可以使用setProps()。
更新组件,我可以在节点上再次调用React.render(),也可以通过setProps()方法改变组件属性,触发组件重新渲染
替换属性:replaceProps
replaceProps(object nextProps[, function callback])
nextProps,将要设置的新属性,该属性会替换当前的props
callback,可选参数,回调函数。该函数会在replaceProps设置成功,且组件重新渲染后调用
replaceProps()方法与setProps类似,但它会删除原有props
强制更新:forceUpdate
forceUpdate([function callback])
callback,可选参数,回调函数。该函数会在组件render()方法调用后调用
forceUpdate()方法会使组件调用自身的render()方法重新渲染组件,组件的子组件也会调用自己的render()。但是,组件重新渲染时,依然会读取this.props和this.state,如果状态没有改变,那么React只会更新DOM。
forceUpdate()方法适用于this.props和this.state之外的组件重绘(如:修改了this.state后),通过该方法通知React需要调用render()
一般来说,应该尽量避免使用forceUpdate(),而仅从this.props和this.state中读取状态并由React触发render()调用
获取DOM节点:findDOMNode
DOMElement findDOMNode()
返回值:DOM元素DOMElement
如果组件已经挂载到DOM中,该方法返回对应的本地浏览器 DOM 元素。当render返回null 或 false时,this.findDOMNode()也会返回null。从DOM 中读取值的时候,该方法很有用,如:获取表单字段的值和做一些 DOM 操作。
判断组件挂载状态:isMounted
bool isMounted()
返回值:true或false,表示组件是否已挂载到DOM中
isMounted()方法用于判断组件是否已挂载到DOM中。可以使用该方法保证了setState()和forceUpdate()在异步场景下的调用不会出错。
React组件生命周期
组件的生命周期可以分为三个状态:- Mounting:已插入真实 DOM
- Updating:正在被重新渲染
- Unmounting:已移出真实 DOM
生命周期的方法有:
- componentWillMount 在渲染前调用,在客户端也在服务端
- componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异部操作阻塞UI)
- componentWillReceiveProps 在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用
- shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 可以在你确认不需要更新组件时使用。
- componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用
- componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用
- componentWillUnmount在组件从 DOM 中移除的时候立刻被调用
以下实例在 Hello 组件加载以后,通过 componentDidMount 方法设置一个定时器,每隔100毫秒重新设置组件的透明度,并重新渲染:
var Hello = React.createClass({ getInitialState: function () { return { opacity: 1.0 }; }, componentDidMount: function () { this.timer = setInterval(function () { var opacity = this.state.opacity; opacity -= .05; if (opacity < 0.1) { opacity = 1.0; } this.setState({ opacity: opacity }); }.bind(this), 100); }, render: function () { return ( <div style={{opacity: this.state.opacity}}> Hello {this.props.name} </div> ); } }); ReactDOM.render( <Hello name="world"/>, document.body );
以下实例初始化 state , setNewnumber 用于更新 state。所有生命周期在 Content 组件中
var Button = React.createClass({ getInitialState: function() { return { data:0 }; }, setNewNumber: function() { this.setState({data: this.state.data + 1}) }, render: function () { return ( <div> <button onClick = {this.setNewNumber}>INCREMENT</button> <Content myNumber = {this.state.data}></Content> </div> ); } }) var Content = React.createClass({ componentWillMount:function() { console.log('Component WILL MOUNT!') }, componentDidMount:function() { console.log('Component DID MOUNT!') }, componentWillReceiveProps:function(newProps) { console.log('Component WILL RECIEVE PROPS!') }, shouldComponentUpdate:function(newProps, newState) { return true; }, componentWillUpdate:function(nextProps, nextState) { console.log('Component WILL UPDATE!'); }, componentDidUpdate:function(prevProps, prevState) { console.log('Component DID UPDATE!') }, componentWillUnmount:function() { console.log('Component WILL UNMOUNT!') }, render: function () { return ( <div> <h3>{this.props.myNumber}</h3> </div> ); } }); ReactDOM.render( <div> <Button /> </div>, document.getElementById('example') );
React AJAX
React 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据库可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI.当使用异步加载数据时,在组件卸载前使用 componentWillUnmount 来取消未完成的请求。
以下实例演示了获取 Github 用户最新 gist 共享描述:
var UserGist = React.createClass({ getInitialState: function() { return { username: '', lastGistUrl: '' }; }, componentDidMount: function() { this.serverRequest = $.get(this.props.source, function (result) { var lastGist = result[0]; this.setState({ username: lastGist.owner.login, lastGistUrl: lastGist.html_url }); }.bind(this)); }, componentWillUnmount: function() { this.serverRequest.abort(); }, render: function() { return ( <div> {this.state.username} 用户最新的 Gist 共享地址: <a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a> </div> ); } }); ReactDOM.render( <UserGist source="https://api.github.com/users/octocat/gists" />, mountNode );
以上代码使用 jQuery 完成 Ajax 请求。
React 表单与事件
一个简单实例
在实例中我们设置了输入框 input 值value = {this.state.data}。在输入框值发生变化时我们可以更新 state。我们可以使用 onChange 事件来监听 input 的变化,并修改 statevar HelloMessage = React.createClass({ getInitialState: function() { return {value: 'Hello Runoob!'}; }, handleChange: function(event) { this.setState({value: event.target.value}); }, render: function() { var value = this.state.value; return <div> <input type="text" value={value} onChange={this.handleChange} /> <h4>{value}</h4> </div>; } }); ReactDOM.render( <HelloMessage />, document.getElementById('example') );
上面的代码将渲染出一个值为 Hello Runoob! 的 input 元素,并通过 onChange 事件响应更新用户输入的值
实例 2
在以下实例中我么将为大家演示如何在子组件上使用表单。 onChange 方法将触发 state 的更新并将更新的值传递到子组件的输入框的 value 上来重新渲染界面。你需要在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp) 传递到你的子组件上。
var Content = React.createClass({ render: function() { return <div> <input type="text" value={this.props.myDataProp} onChange={this.props.updateStateProp} /> <h4>{this.props.myDataProp}</h4> </div>; } }); var HelloMessage = React.createClass({ getInitialState: function() { return {value: 'Hello Runoob!'}; }, handleChange: function(event) { this.setState({value: event.target.value}); }, render: function() { var value = this.state.value; return <div> <Content myDataProp = {value} updateStateProp = {this.handleChange}></Content> </div>; } }); ReactDOM.render( <HelloMessage />, document.getElementById('example') );
React 事件
以下实例演示通过 onClick 事件来修改数据:var HelloMessage = React.createClass({ getInitialState: function() { return {value: 'Hello Runoob!'}; }, handleChange: function(event) { this.setState({value: '菜鸟教程'}) }, render: function() { var value = this.state.value; return <div> <button onClick={this.handleChange}>点我</button> <h4>{value}</h4> </div>; } }); ReactDOM.render( <HelloMessage />, document.getElementById('example') );
当你需要从子组件中更新父组件的 state 时,你需要在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp) 传递到你的子组件上。实例如下:
var Content = React.createClass({ render: function() { return <div> <button onClick = {this.props.updateStateProp}>点我</button> <h4>{this.props.myDataProp}</h4> </div> } }); var HelloMessage = React.createClass({ getInitialState: function() { return {value: 'Hello Runoob!'}; }, handleChange: function(event) { this.setState({value: '菜鸟教程'}) }, render: function() { var value = this.state.value; return <div> <Content myDataProp = {value} updateStateProp = {this.handleChange}></Content> </div>; } }); ReactDOM.render( <HelloMessage />, document.getElementById('example') );
React Refs
React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例。
使用方法
绑定一个 ref 属性到 render 的返回值上:<input ref="myInput" />
在其它代码中,通过 this.refs 获取支撑实例:
var input = this.refs.myInput; var inputValue = input.value; var inputRect = input.getBoundingClientRect();
完整实例
你可以通过使用 this 来获取当前 React 组件,或使用 ref 来获取组件的引用,实例如下:var MyComponent = React.createClass({ handleClick: function() { // 使用原生的 DOM API 获取焦点 this.refs.myInput.focus(); }, render: function() { // 当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs return ( <div> <input type="text" ref="myInput" /> <input type="button" value="点我输入框获取焦点" onClick={this.handleClick} /> </div> ); } }); ReactDOM.render( <MyComponent />, document.getElementById('example') );
实例中,我们获取了输入框的支撑实例的引用,子点击按钮后输入框获取焦点。
我们也可以使用 getDOMNode()方法获取DOM元素。
转载请标注地址:Geek马走日
Follow个人Github : mazouri
相关文章推荐
- [深入剖析React Native]热更新之react-native-pushy使用指南(IOS)
- [深入剖析React Native]热更新之react-native-pushy使用指南(Android)
- [深入剖析React Native]React Native Flexbox属性讲解
- [深入剖析React Native]React Native组件之Touchable*源码解析(1)
- [深入剖析React Native]React Native组件之Navigator
- [深入剖析React Native]React Native组件之Touchable*
- [深入剖析React Native]手势响应讲解
- [置顶] [深入剖析React Native总贴]React Native学习路线
- [深入剖析React Native]手势响应讲解
- [置顶] [深入剖析React Native总贴]React Native学习路线
- [深入剖析React Native]坑坑汇总
- YARN/MRv2 Node Manager深入剖析—整体架构
- 深入剖析 redis 数据结构 ziplist
- 深入react技术栈--(1)简单了解
- Java Web开发详解——XML+DTD+XML Schema+XSLT+Servlet 3.0+JSP 2.2深入剖析与实例应用
- 【React Native开发】React Native移植原生Android项目(4)
- float深入剖析
- Vector、ArrayList、List使用深入剖析
- 在Android原生中嵌入React Native,进而React Native调用原生
- 深入剖析ExtJS 2.2实现及应用连载(11): 左边导航菜单