React初探
React 特点
简单Demo<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello React!</title> <script src="http://static.runoob.com/assets/react/react-0.14.7/build/react.min.js"></script> <script src="http://static.runoob.com/assets/react/react-0.14.7/build/react-dom.min.js"></script> <script src="http://static.runoob.com/assets/react/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.min.js 、react-dom.min.js 和 browser.min.js: React代码<script type="text/babel"></script> React JSX语法React 使用 JSX 来替代常规的 JavaScript。JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。我们不需要一定使用 JSX,但它有以下优点:
它是类型安全的,在编译过程中就能发现错误。 简单嵌套元素JSX 看起来类似 HTML ,我们可以看下实例: 实例:Hello,world!ReactDOM.render(content,element); ReactDOM.render(<h1>Hello,document.getElementById('example')); index1 复杂嵌套元素我们可以在以上代码中嵌套多个 HTML 标签,需要使用一个 div 元素包裹它,实例中的 p 元素添加了自定义属性 data-myattribute,添加自定义属性需要使用 data- 前缀。 实例:文字ReactDOM.render( <div> <h1>菜鸟教程</h1> <h2>欢迎学习 React</h2> <p data-myattribute = "somevalue">这是一个很不错的 JavaScript 库!</p> </div>,mountNode ); index2 JavaScript 表达式我们可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。实例如下: 实例:计算ReactDOM.render( <div><h1>{1+1}</h1></div>,mountNode ); index3
在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代。以下实例中如果变量 i 等于 1 浏览器将输出 true,如果修改 i 的值,则会输出 false. 实例:判断const i = 1; ReactDOM.render( <div> <h1>{i == 1 ? 'True!' : 'False'}</h1> </div>,mountNode ); index4 样式React 推荐使用内联样式。我们可以使用 camelCase 语法来设置内联样式. React 会在指定元素数字后自动添加 px 。以下实例演示了为 h1 元素添加 myStyle 内联样式: 实例:CSS样式const myStyle = { fontSize: 100,lineHeight: '30px',color: '#FF0000' }; ReactDOM.render( <h1 style = {myStyle}>菜鸟教程</h1>,mountNode ); ReactDOM.render(<h1 style = {{fontSize: 100,color: '#FF0000'}}>菜鸟教程</h1>,mountNode); ReactDOM.render(<h1 className = 'class_name'>菜鸟教程</h1>,mountNode); index5 注释注释需要写在花括号中,实例如下: 实例:注释ReactDOM.render( <div> <h1>菜鸟教程</h1> {/*注释...*/} </div>,mountNode ); React.Component组件基础语法HTML 标签 vs. React 组件React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes)。要渲染 HTML 标签,只需在 JSX 里使用小写字母的标签名。 实例:创建组件class DivElement extends React.Component{ render() { return ( <div className="foo">arr</div> ); } } ReactDOM.render(<DivElement />,mountNode); 实例:组件嵌套class MyComponent extends React.Component{ render() { return <div className="MyComponent">arr</div>; } } class DivElement extends React.Component{ render() { return <MyComponent />; } } ReactDOM.render(<DivElement />,mountNode); React 的 JSX 使用大、小写的约定来区分本地组件的类和 HTML 标签。
由于 JSX 就是 JavaScript,一些标识符像 class 和 for 不建议作为 XML 属性名。作为替代,React DOM 使用 className 和 htmlFor 来做对应的属性。 实例:组件语法class HelloMessage extends React.Component{ render() { return <div className="HelloMessage">arr</div>; } } class HelloMessage extends React.Component{ render() { return ( <div className="HelloMessage">arr</div> ); } } React.Component方法用于生成一个组件类 HelloMessage。<HelloMessage /> 实例组件类并输出信息。
如果我们需要向组件传递参数,可以使用 this.props 对象,实例如下: 实例:获取父元素的值class DivElement extends React.Component{ render() { return ( <div className="foo">{this.props.name}</div> ); } } ReactDOM.render(<DivElement name="Runoob" />,mountNode); 以上实例中 name 属性通过 this.props.name 来获取(自身的数字)。 复合组件通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。 实例:链接class WebSite extends React.Component{ render() { return ( <div className={this.props.name}><Name name={this.props.name} /><Link site={this.props.site} /></div> ); } } class Name extends React.Component{ render() { return ( <h1>{this.props.name}</h1> ); } } class Link extends React.Component{ render() { return ( <a href={this.props.site}>{this.props.site}</a> ); } } ReactDOM.render(<WebSite name="菜鸟教程" site=" http://www.runoob.com" />,mountNode); React State(状态)把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。 constructor()初始状态实例:点击喜欢&不喜欢class LikeButton extends React.Component{ constructor() { super(); this.state ={liked: false}; } handleClick() { this.setState({ liked: !this.state.liked }); } render() { let text = this.state.liked ? '喜欢' : '不喜欢'; return ( <p onClick={this.handleClick.bind(this)}>你<b>{text}</b>我。点我切换状态。</p> ); } }; ReactDOM.render(<LikeButton />,mountNode); handleClick = ()=>{ this.setState({ liked: !this.state.liked }); } constructor是组件的构造函数,会在创建实例时自动调用。 实例:输入文字实时显示class MyTitle extends React.Component{ constructor() { super(); this.state ={name: 'can you speek English!'}; } handleChange(e) { let name = e.target.value; this.setState({ name: name }); } render() { return ( <div> <input type="text" onChange={this.handleChange.bind(this)} /> <p>luuman,{this.state.name}</p> </div> ); } } ReactDOM.render(<MyTitle />,mountNode); React Propsprops通过组件获取数据 基础语法实例:数据传递class HelloMessage extends React.Component{ render(){ return <h1>Hello {this.props.name}</h1>; } } ReactDOM.render( <HelloMessage name="Runoob" />,mountNode ); 实例中 name 属性通过 this.props.name 来获取。 defaultProps默认值默认Props:你可以通过defaultProps()方法为props设置默认值,实例如下: class HelloMessage extends React.Component{ render(){ return <h1>Hello {this.props.name}</h1>; } } HelloMessage.defaultProps = { name: 'Runoob' } ReactDOM.render(<HelloMessage />,mountNode); class WebSite extends React.Component{ render() { return ( <div className={this.props.name}><Name name={this.props.name} /><Link site={this.props.site} /></div> ); } } WebSite.defaultProps ={ name: "菜鸟教程",site: "http://www.runoob.com" } class Name extends React.Component{ render() { return ( <h1>{this.props.name}</h1> ); } } class Link extends React.Component{ render() { return ( <a href={this.props.site}>{this.props.site}</a> ); } } ReactDOM.render(<WebSite />,mountNode); this.props.children实例:点击次数class NotesList extends React.Component{ render(){ return( <ol>{ React.Children.map(this.props.children,function(child){ console.log(child); return <li>{child}</li> }) }</ol> ); } } ReactDOM.render( <NotesList> <span>hello</span> <span>world</span> <span>world</span> <span>world</span> </NotesList>,mountNode ); PropTypes验证Props 使用propTypes,它可以保证我们的应用组件被正确使用,React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。 实例:判断组件属性title是否为字符串:const name = 123; console.log(name); class HelloMessage extends React.Component{ render(){ return <h1>Hello {this.props.title}</h1>; } } HelloMessage.propTypes = { title: React.PropTypes.string } ReactDOM.render(<HelloMessage title={name} />,mountNode);
Warning: Failed prop type: Invalid prop `title` of type `number` supplied to `HelloMessage`,expected `string`. PropTypes属性值.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,optionalSymbol: React.PropTypes.symbol,// 可以被渲染的对象 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(props,propName,componentName) { if (!/matchme/.test(props[propName])) { return new Error( 'Invalid prop `' + propName + '` supplied to' + ' `' + componentName + '`. Validation failed.' ); } },customArrayProp: React.PropTypes.arrayOf( function(propValue,key,componentName,location,propFullName) { if (!/matchme/.test(propValue[key])) { return new Error( 'Invalid prop `' + propFullName + '` supplied to' + ' `' + componentName + '`. Validation failed.' ); } } ) } state和props区别在于props是不可变的,而子组件只能通过props来获取数据。 以下实例演示了如何在应用中组合使用state和props。我们可以在父组件中设置state,并通过在子组件上使用props将其传递到子组件上。在render函数中,我们设置name和site来获取父组件传递过来的数据。 实例:链接class WebSite extends React.Component{ constructor(props) { super(props); this.state = { name: "菜鸟教程",site: "http://www.runoob.com" }; } render(){ return <div><Name name={this.state.name} /><Link site={this.state.site} /></div> } } class Name extends React.Component{ render(){ return <h1>{this.props.name}</h1> } } class Link extends React.Component{ render(){ return <a href={this.props.site}>{this.props.site}</a> } } ReactDOM.render(<WebSite />,mountNode); React 组件 API在本章节中我们将讨论 React 组件 API。 基础语法mixins去重const ExampleMixin = { componentDidMount(){ // bind some event listeners here } componentWillUnmount(){ // unbind those events here! } } class ExampleComponent extends React.Component{ mixins: [ExampleMixin]; render(){} } class AnotherComponent extends React.Component{ mixins: [ExampleMixin]; render(){} } <!-- 设置状态:setState 实例:点击次数class Counter extends React.Component{ constructor(){ super(); this.state = { clickCount: 0 }; } handleClick(){ this.setState({ clickCount: this.state.clickCount +1 }); } render(){ return <h2 onClick={this.handleClick.bind(this)}>点我!点击次数为: {this.state.clickCount}</h2>; } } ReactDOM.render(<Counter />,mountNode); <!-- React 组件生命周期
Mounting:已插入真实 DOMconstructor()componentWillMount()在渲染前调用,在客户端也在服务端。 render()在渲染时调用 componentDidMount()在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 Updating:正在被重新渲染componentWillReceiveProps()在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用。 shouldComponentUpdate()返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 componentWillUpdate()在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。 render()componentDidUpdate()在组件完成更新后立即调用。在初始化时不会被调用。 Unmounting:已移出真实 DOMcomponentWillUnmount()在组件从 DOM 中移除的时候立刻被调用。 实例:定时器,每隔100毫秒重新设置组件的透明度,并重新渲染class Hello extends React.Component{ constructor() { super(); this.state = { opacity: 1.0 } } componentDidMount(){ this.timer = setInterval(function(){ let opacity = this.state.opacity; opacity -= .05; if(opacity < .1){ opacity = 1.0; } this.setState({ opacity: opacity }) }.bind(this),100) } render(){ return( <div style={{opacity: this.state.opacity}}> Hello {this.props.name} </div> ) } } ReactDOM.render(<Hello name="world" />,mountNode); 实例:点击效果以下实例初始化 state , setNewnumber 用于更新 state。所有生命周期在 Content 组件中。 class Button extends React.Component{ constructor() { super(); this.state = { data:0 } } setNewNumber(){ this.setState({ data: this.state.data + 1 }) } render(){ return( <div> <button onClick={this.setNewNumber.bind(this)}>INCREMENT</button> <Content myNumber={this.state.data}></Content> </div> ) } } class Content extends React.Component{ componentWillMount(){ console.log('Component WILL MOUNT!') } componentDidMount(){ console.log('Component DID MOUNT!') } componentWillReceiveProps(newProps) { console.log('Component WILL RECEIVE PROPS!') } shouldComponentUpdate(newProps,newState) { return true; } componentWillUpdate(nextProps,nextState) { console.log('Component WILL UPDATE!'); } componentDidUpdate(prevProps,prevState) { console.log('Component DID UPDATE!') } componentWillUnmount(){ console.log('Component WILL UNMOUNT!') } render(){ return( <div> <h3>{this.props.myNumber}</h3> </div> ) } } ReactDOM.render(<Button />,mountNode); 实例:统计时间class Timer extends React.Component{ constructor(props) { super(props); this.state = {secondsElapsed: 0}; } tick(){ this.setState((prevState) => ({ secondsElapsed: prevState.secondsElapsed + 1 })); } componentDidMount(){ this.interval = setInterval(() => this.tick(),1000); } componentWillUnmount(){ clearInterval(this.interval); } render(){ return ( <div>Seconds Elapsed: {this.state.secondsElapsed}</div> ); } } ReactDOM.render(<Timer />,mountNode); Lists and Keys列表遍历JSX 允许在模板中插入数组,数组会自动展开所有成员: const arr = [ <h1>菜鸟教程</h1>,<h2>学的不仅是技术,更是梦想!</h2>,]; ReactDOM.render( <div>{arr}</div>,mountNode ); index6 Array.mapconst numbers = [1,2,3,4,5]; const doubled = numbers.map((number) => number * 2); console.log(doubled); const numbers = [1,5]; const listItems = numbers.map((number,key) => <li key={key}>{number}</li> ); console.log(listItems); ReactDOM.render(<ul>{listItems}</ul>,mountNode); const listItems = numbers.map(function(number,keys){ return( <li key={keys}> {number} </li> ) }); Array.forEach 遍历Array.forEach((e) => { alert(e); }) Array.forEach(function(e){ alert(e); }) let repos = this.state.data.items; let repoList = []; repos.forEach((p,keys) => { let item = <li key={keys}><a href={p.html_url}>{p.name}</a>({p.stargazers_count} stars)<br />{p.description}</li>; repoList.push(item); }) let repos = this.state.data.items; let repoList = repos.map(function(repo,index){ return( <li key={index}> <a href={repo.html_url}>{repo.name}</a>({repo.stargazers_count} stars)<br /> {repo.description} </li> ); }); Array.splice 删除Array.filter方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素 Array.everyArray.pushHandling Events绑定事件Forms表单基础语法实例:输入文字实时显示class HelloMessage extends React.Component{ constructor(){ super(); this.state = { value: 'Hello World!' }; } handleChange(even){ this.setState({ value: even.target.value }) } render(){ let value = this.state.value; return( <div> <input type='text' value={value} onChange={this.handleChange.bind(this)} /> <h4>{value}</h4> </div> ); } } ReactDOM.render(<HelloMessage />,mountNode); 实例:输入文字实时显示你需要在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp) 传递到你的子组件上。 class Content extends React.Component{ render(){ return( <div> <input type='text' value={this.props.myDataProp} onChange={this.props.updataStateProp} /> <h4>{this.props.myDataProp}</h4> </div> ) } } class HelloMessage extends React.Component{ constructor(){ super(); this.state = { value: 'Hello World!' }; } handleChange(even){ this.setState({ value: even.target.value }) } render(){ let value = this.state.value; return( <div> <Content myDataProp={value} updataStateProp={this.handleChange.bind(this)} /> </div> ); } } ReactDOM.render(<HelloMessage />,mountNode); 实例:点我class HelloMessage extends React.Component{ constructor(){ super(); this.state={ value: 'Hello World!' } } handleChange(event){ this.setState({ value: 'luuman is good man!' }) } render(){ let value = this.state.value; return( <div> <button onClick={this.handleChange.bind(this)}>点我</button> <h4>{value}</h4> </div> ) } } ReactDOM.render(<HelloMessage />,mountNode); 当你需要从子组件中更新父组件的 state 时,你需要在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp) 传递到你的子组件上。实例如下: 实例:点我class Content extends React.Component{ render(){ return( <div> <button onClick={this.props.updateStateProp}>点我</button> <h4>{this.props.myDataProp}</h4> </div> ) } } class HelloMessage extends React.Component{ constructor(){ super(); this.state = { value: 'Hello World!' } } handleChange(event){ this.setState({ value: 'luuman is good man!' }) } render(){ let value = this.state.value; return <div><Content myDataProp={value} updateStateProp={this.handleChange.bind(this)}></Content></div> } } ReactDOM.render(<HelloMessage />,mountNode); Refs and the DOMReact RefsReact 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。
在其它代码中,通过 this.refs 获取支撑实例: <input ref="myInput" /> var input = this.refs.myInput; var inputValue = input.value; var inputRect = input.getBoundingClientRect(); 实例:点我输入框获取焦点class MyComponent extends React.Component{ handleClick(){ this.refs.myInput.focus(); } render(){ return( <div> <input type='text' ref='myInput' /> <input type='button' value='点我输入框获取焦点' onClick={this.handleClick.bind(this)} /> </div> ); } } ReactDOM.render(<MyComponent />,mountNode); 当组件插入到 DOM 后,ref属性添加一个组件的引用于到this.refs.name获取。 实例中,我们获取了输入框的支撑实例的引用,子点击按钮后输入框获取焦点。 React AJAXReact 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据库可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI。 实例$.get(URL,function(data){}) 实例:获取 Github 用户最新 gist 共享描述:class UserGist extends React.Component{ constructor() { super(); this.state = { username: '',lastGistUrl: '' } } componentDidMount(){ this.serverRequest = $.get(this.props.source,function(result){ let lastGist = result[0]; this.setState({ username: lastGist.owner.login,lastGistUrl: lastGist.html_url }) }.bind(this)) } componentWillUnmount(){ this.serverRequest.abort(); } render(){ return( <div> {this.state.username} <a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a> </div> ) } } ReactDOM.render(<UserGist source="https://api.github.com/users/octocat/gists" />,mountNode); 实例:拉取数据import $ from 'jquery'; import React from 'react'; import ReactDOM from 'react-dom'; const mountNode = document.getElementById('root'); class RipoList extends React.Component{ constructor(){ super(); this.state = { loading: true,error: null,data: null }; } componentDidMount(){ this.props.promise.then( value => this.setState({ loading: false,data: value }),error => this.setState({ loading: false,error: error }) ); } render(){ if(this.state.loading){ return <span>Loading...</span>; }else if(this.state.error != null){ return <span>Error: {this.state.error.message}</span>; }else{ let repos = this.state.data.items; let repoList = repos.map(function(repo,index){ return( <li key={index}> <a href={repo.html_url}>{repo.name}</a>({repo.stargazers_count} stars)<br /> {repo.description} </li> ); }); return( <main> <h1>Most Popular JavaScript Projects in Github</h1> <ol>{repoList}</ol> </main> ) } } } ReactDOM.render(<RipoList promise={$.getJSON('https://api.github.com/search/repositories?q=javascript&sort=stars')} />,mountNode); Add-Ons 添加插件jqueryimport $ from 'jquery'; import React from 'react'; import ReactDOM from 'react-dom'; class HelloWorld extends React.Component{ render(){ return( <div>HelloWorld</div> ); } } ReactDOM.render(<HelloWorld />,$('#example')[0]); recharts
bootstrap
MarkdownEditor
ReactDOMrender()ReactDOM.render( element,container,[callback] ) unmountComponentAtNode()ReactDOM.unmountComponentAtNode(container) findDOMNode()ReactDOM.findDOMNode(component) onkeypress/* 在实例中,我们使用了支持多浏览器的方法,因为 keyCode 属性无法再 Firefox 浏览器中工作。但是 which 属性可以。 ES6ECMAScript 6 入门 let用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
for (let i = 0; i < 10; i++) {} console.log(i); //ReferenceError: i is not defined
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- com.alibaba.fastjson.JSONException: not close json text
- red5流媒体服务器的安装与配置(FLEX与JAVA的结合)
- 读取xml数据
- C#尝试/捕捉噩梦
- Sklearn学习之路(2)——围绕评估器转换器展开讨论
- 用oracle12的windows的Docker镜像
- 【OpenCV笔记 16-1】OpenCV人脸检测之Haar分类器
- ruby-on-rails – rspec-mocks’的双打仅设计为一个例子
- Alamofire Swift 3.0呼叫中的额外参数
- 使用基于@ResponseBody注释的MappingJackson2JsonView支持在