网址收藏: React官网,React的Github,React的中文文档javascript
React起源于Facebook的内部项目,由于该公司对市场上全部的Javascript MVC框架都不满意,决定本身写一套,用来架设Instargm的网站。作完之后,发现很好用,就在2013年5月开源。html
npm install create-react-app -g
git clone git@github.com:ruanyf/react-demos.git
下载下来重点:组件,状态 核心: 状态java
<!DOCTYPE html>
<html>
<head>
<!-- 这是核心js -->
<script src="../build/react.js"></script>
<!-- 这是处理虚拟dom相关的js -->
<script src="../build/react-dom.js"></script>
<!-- 这是把JSX语法转换为js语法 (注意:JSX就是能够把html写在js里面。) -->
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<!-- 这里加type就是告诉游览器,这里使用的是JSX语法模板。 -->
<script type="text/babel"> //这里写 </script>
</body>
</html>
复制代码
React最基本的方法,用于把模板转换成html语言,而且插入指定的节点。react
例如:jquery
ReactDOM.render(
<h2>Welcome to React World!</h2>,
document.getElementById('myapp')
)
复制代码
JSX是能够在js中写html,遇到html标签(例如:
<
)就用html
解析,遇到代码块(例如:{
)就用javascript规则解析。git
例如:github
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<div id="food"></div>
<script type="text/babel"> var names = ['Alice', 'Emily', 'Kate']; var foods = ['meal','sala','milk']; ReactDOM.render( <div> { names.map(function (name, index) { return <div key={index}>Hello, {name}!</div> }) } </div>, document.getElementById('example') ); ReactDOM.render( <div> { foods.map(function (food, index) { return <div key={index}>I like eat {food}!</div> }) } </div>, document.getElementById('food') ) </script>
</body>
</html>
复制代码
React容许将代码封装成组件(component),而后把它当成html标签插入到网页中。React.createClass()就是能够建立一个组建类。npm
例如:api
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="foods"></div>
<script type="text/babel"> var LikeFood = React.createClass({ //建立组件类 render: function() { return <p>I like eat <mark>{this.props.name}</mark></p>; } }); ReactDOM.render( <LikeFood name="Apple"/>, document.getElementById('foods') ) </script>
</body>
</html>
复制代码
this.props
对象的属性与组件的属性基本上是一致的,特殊在于this.props.children
属性,它表示组件的全部子节点。数组
注意: this.props.children
有三个可能,若是当前组件没有子节点,就是显示undefined
;若是有一个子节点,数据类型就是object
;若是有多个子节点,就是array
,因此要当心。 但React提供了一个方法遍历全部子节点,React.Children
,经过this.props.children
来遍历。
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="foods"></div>
<script type="text/babel"> var FoodList = React.createClass({ render: function() { return ( <ul> { React.Children.map(this.props.children,function (child) { return <li>{child}</li>; }) } </ul> ) } }) ReactDOM.render( <FoodList> <span>Hello,</span> <span>I like eat</span> <span>Apple!</span> </FoodList>, document.getElementById('foods') ) </script>
</body>
</html>
复制代码
组件的属性能够接受任何值,如字符串,数字,数组,对象,函数,可是须要一种机制来验证使用组件提供的参数是否符合要求,PropTypes就是用来验证这个的。
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="foods"></div>
<script type="text/babel"> var str = 123; var MyNum = React.createClass({ propTypes: { num: React.PropTypes.number.isRequired, }, render: function() { return <h2>{this.props.num}</h2> } }); ReactDOM.render( <MyNum num={str} />, document.getElementById('foods') ) </script>
</body>
</html>
复制代码
补充: 还能够添加默认值。'
getDefaultProps: function() {
return {
num: 1818
}
}
复制代码
例如:
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="foods"></div>
<script type="text/babel"> var str; var MyNum = React.createClass({ getDefaultProps: function() { return { num: 1818 } } propTypes: { num: React.PropTypes.number.isRequired, }, render: function() { return <h2>{this.props.num}</h2> } }); ReactDOM.render( <MyNum num={str} />, document.getElementById('foods') ) </script>
</body>
</html>
复制代码
组件并非真的dom节点,只是存在内存中的数据结构,叫作虚拟DOM(virtual)。当它插入到文档之后,才会变成真实的DOM。
全部的DOM变更,先是在虚拟DOM上发生变更,而后再在实际发生变更的部分,反映在真实的DOM,这种叫作DOM diff,它能够极大提升网页的性能表现。
有时须要从组件获取真实的DOM的节点,这个时候就要用到ref
属性。
注意: React还支持许多事件,更多请访问事件。
例如:
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="foods"></div>
<script type="text/babel"> var MyFoods = React.createClass({ showContent: function() { this.refs.myFoodInput.focus(); }, render: function() { return ( <div> <input type="text" ref="myFoodInput" /> <input type="button" value="自动聚焦" onClick={this.showContent} /> </div> ) } }) ReactDOM.render( <MyFoods />, document.getElementById('foods') ) </script>
</body>
</html>
复制代码
组件免不了要和用户互动,React的一大创新就是把组件当作是一个状态机,一开始有个初始状态,而后用户互动,致使状态变化,从而从新出发渲染UI。
注意: getInitialState
方法用于定义初始状态,但同时它是一个对象,这个能够经过this.state
属性读取。
当用户点击组件,致使状态发生变化,this.setState
方法就会修改状态值,每次修改完,会自动调用this.render
方法,再次渲染组件。
this.props
和this.state
都是描述组件的特性,可是不一样的是this.props
是指一旦定义好了,就再也不发生变化的特性,而this.state
是会随着用户互动而产生变化的特性。
例如:
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="foods"></div>
<script type="text/babel"> var FoodButton = React.createClass({ getInitialState: function() { return {food: false}; }, callClick: function(event) { this.setState({food: !this.state.food}); }, render: function() { var text1 = this.state.food ? 'like eat apple' : 'hate eat apple'; return ( <p onClick={this.callClick}> You {text1}! </p> ); } }); ReactDOM.render( <FoodButton />, document.getElementById('foods') ) </script>
</body>
</html>
复制代码
用户在表单填入的内容,属于用户和组件之间的互动,因此不能用
this.state
,而要定义一个onChange
事件的回调函数,经过event.target.value
读取用户的值。
注意:textarea
,select
,radio
都属于这种状况。
例如:
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="food"></div>
<script type="text/babel"> var Food = React.createClass({ getInitialState: function() { return {val: 'Welcome to React!'}; }, hanChange: function(event) { this.setState({val:event.target.value}); }, render: function() { var val = this.state.val; return ( <div> <input type="text" value={val} onChange={this.hanChange} /> <p>{val}</p> </div> ); } }) ReactDOM.render(<Food />,document.getElementById('food')) </script>
</body>
</html>
复制代码
React中组件的生命周期分为三个状态,Mounting是已经插入真实DOM,Updating是正在被从新渲染,Unmounting是已移出真实DOM。
每一个状态都有两种处理函数,will函数是进入状态以前,did函数是进入状态以后,三种状态共计五种函数。
注意:组件的样式style不能写成<div style={opacity: this.state.opacity}>
,要写成<div style={{opacity: this.state.opacity}}>
。
由于React组件样式是个对象,因此第一个大括号表示Javascript语法,第二个大括号表示样式对象。
componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentWillUpdate(object prevState, object prevState)
componentWillUnMount()
例如:第二种,在已插入真实DOM以后触发。
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="food"></div>
<script type="text/babel"> var Food = React.createClass({ getInitialState: function() { return { opacity: 0 } }, componentDidMount: function() { this.timer = setInterval(function() { var opacity = this.state.opacity; opacity += .05; if (opacity > 1) { opacity = 0; } this.setState({ opacity: opacity }) }.bind(this),100); }, render: function() { return ( <div style={{opacity: this.state.opacity}}> Hello, {this.props.title} </div> ); } }); ReactDOM.render( <Food title="apple"/>, document.getElementById('food') ) </script>
</body>
</html>
复制代码
组件的数据来源通常都是经过Ajax请求从服务器获取,可使用
componentDidMount()
方法设置Ajax请求,等到请求成功,再用this.setState
方法从新渲染UI。
例如:
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
<script src="../build/jquery.min.js"></script>
</head>
<body>
<div id="food"></div>
<script type="text/babel"> var ClientGits = React.createClass({ getInitialState: function() { return { id: '', addr: '' }; }, componentDidMount: function() { $.get(this.props.source,function (result) { var gits = result[0]; this.setState({ id: gits.id, addr: gits.git_pull_url }); }.bind(this)); }, render: function() { return ( <div> UserId is <a href='#userId'>{this.state.id}</a>, Git Address is <a href={this.state.addr}>{this.state.addr}</a>! </div> ); } }); ReactDOM.render( <ClientGits source="https://api.github.com/users/octocat/gists" />, document.getElementById('food') ) </script>
</body>
</html>
复制代码
注意: 上面采用了jquery的Ajax,还能够采用其余的库。咱们甚至能够把Promise对象传入组件。
例如:
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
<script src="../build/jquery.min.js"></script>
</head>
<body>
<div id="projects"></div>
<script type="text/babel"> var Projects = React.createClass({ getInitialState: function() { return { 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: function() { if (this.state.loading) { return <span>Loading...</span>; } else if (this.state.error != null) { return <span>Error:{this.state.error.message}</span>; } else { var res = this.state.data.items; var resList = res.map(function (res,index) { return ( <li key={index}><a href={res.html_url} target="_blank">{res.name}</a>({res.stargazers_count} stars)<br/>{res.description}</li> ); }); return ( <main> <h1>Github上最受欢迎的JS项目</h1> <ul>{resList}</ul> </main> ); } } }); ReactDOM.render( <Projects promise={$.getJSON('https://api.github.com/search/repositories?q=javascript&sort=stars')} />, document.getElementById('projects') ) </script>
</body>
</html>
复制代码
之后还会总结一些有关react的知识点。