2.模块化与组件化
声明式编程和命令式编程
var arr = [1, 3, 5, 7]
// 需求: 得到一个新的数组, 数组中每个元素都比arr中对应的元素大10: [11, 13, 15, 17]
// 命令式编程
var arr2 = []
for(var i =0;i10)
}
console.log(arr2)
// 声明式编程
var arr3 = arr.map(function(item){
return item +10
})
// 声明式编程是建立命令式编程的基础上
JSX
1). 理解
作用: 用来创建react虚拟DOM(元素)对象;
var ele = <h1>Hello JSX!h1>;
2). 编码相关
把数据的数组转换为标签的数组:
var liArr = dataArr.map(function(item, index){
return - {index}>{item}
})
babel.js的作用
3). 注意:
虚拟DOM
1). React提供了一些API来创建一种 特别
的一般js对象;
//创建的就是一个简单的虚拟DOM对象
var element = React.createElement('h1', {id:'myTitle'}, 'hello');
2). 虚拟DOM对象最终都会被React转换为真实的DOM;
4).创建虚拟DOM的2种方式:
1). 纯JS(一般不用):
// 纯JS方式
const msg = 'I like you';
const myId = 'atguigu';
const vDOM1 = React.createElement('h2',{id:myId},msg);
2). JSX方式:
// jsx方式创建虚拟dom元素对象
const vDOM2 = <h3 id={myId.toUpperCase()}>{msg.toLowerCase()}h3>
5).渲染虚拟DOM(元素)
// 渲染到真实的页面中
ReactDOM.render(vDOM1,document.getElementById('example1'));
ReactDOM.render(vDOM2,document.getElementById('example2'));
<html>
<head>
<meta charset="UTF-8">
<title>02_JSX_DEMOtitle>
head>
<body>
<ul>
<li>Ali>
<li>Bli>
<li>Cli>
ul>
<hr>
<div id="example1">div>
<div id="example2">div>
<script src="../js/react.js">script>
<script src="../js/react-dom.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
/*
功能: 动态展示列表数据
*/
/*
技术点:
1). 使用JSX创建虚拟DOM
2). React能自动遍历显示数组中所有的元素
3). array.map()的使用
*/
//数据的数组
var names = ['Tom2', 'Jack2', 'Bob2'];
//数据的数组——>标签数组
var lis = [];
names.forEach((item,index)=>lis.push(<li key={index}>{item}li>));
//创建虚拟的DOM
const ul=<ul>{lis}ul>;
// 将虚拟的Dom渲染到页面中的某个DOM元素中
ReactDOM.render(ul,document.getElementById('example1'))
const ul2 = <ul>{names.map((name,index)=><li key={index}>{name}li>)}ul>
ReactDOM.render(ul2, document.getElementById('example2'))
script>
body>
html>
// 方式一:工厂函数,推荐使用
function MyComponent() {
return <h2>工厂函数h2>
}
// 方式二:ES6类语法(复杂组件,推荐使用)
class MyComponent2 extends React.Component{
render(){
return ES6的语法
}
}
// 方式三:ES5的老语法
const MyComponent3 = React.createClass({
render(){
return EES5老语法(不推荐使用了)
}
})
//语法规则
ReactDOM.render( , document.getElementById('example'));
// 二:渲染组件标签
ReactDOM.render( ,document.getElementById('example1'));
ReactDOM.render( ,document.getElementById('example2'));
ReactDOM.render( ,document.getElementById('example3'));
// 对标签属性进行限制
Person.propTypes = {
name:React.PropTypes.string.isRequired,
sex:React.PropTypes.string,
age:React.PropTypes.number
}
<Person {...person}/>
//具体如下:
ReactDOM.render(<Person {...person}/>,document.getElementById('example'))
// 指定属性的默认值
Person.defaultProps = {
sex:'男',
age:18
}
constructor (props) {
super(props)
console.log(props) // 查看所有属性
}
ref='username'>
this.refs.username //返回input对象
this.handleClick}/>
handleFocus(event) {
event.target //返回input对象
}
强烈注意
2). 在组件中自定义的方法中的this为null;
强制绑定this;
this.change = this.change.bind(this);
箭头函数(ES6模块化编码时才能使用);
constructor (props) {
super(props)
this.state = {
stateProp1 : value1,
stateProp2 : value2
}
}
3). 读取某个状态值
this.state.statePropertyName
4). 更新状态—->组件界面更新
this.setState({
stateProp1 : value1,
stateProp2 : value2
})
5). 问题: 请区别一下组件的props和state属性?
3.生命周期流程:
第一次初始化渲染显示: render()
每次更新state: this.setSate()
//测试
class MyComponent extends React.Component{
constructor(props){
super(props)
this.state = {
msg:'这只是一句话而已'
}
}
componentWillMount(){
console.log('componentWillMount')
//启动一个定时器,更新状态
setTimeout(function () {
this.setState({msg:Date.now()})
}.bind(this),2000)
//启动一个定时器,移除组件
setTimeout(function () {
ReactDOM.unmountComponentAtNode(document.getElementById('example'))
},4000)
}
render(){
console.log('render()')
const {msg}=this.state
return {msg}
}
componentDidMount(){
console.log('componentDidMount')
}
componentWillUpdate () {
console.log('componentWillUpdate')
}
componentDidUpdate () {
console.log('componentDidUpdate')
}
componentWillUnmount () {
console.log('componentWillUnmount')
}
}
ReactDOM.render( ,document.getElementById('example'))
//一个小练习,文字渐隐
class Fade extends React.Component{
constructor(props){
super(props)
this.state={
opacity:1
}
}
componentDidMount(){
//在此方法中启动定时器/绑定监听/发送Ajax请求
this.intervalId=setInterval(function () {
//保存到当前组件对象中
let {opacity}=this.state
//操作当前的数据。
opacity -= 0.1
// 更新状态
this.setState({opacity})
}.bind(this),500)
}
componentWillUnmount(){
//清除定时器/解除监听
clearInterval(this.intervalId)
}
removeComp(){
//移除组件
ReactDOM.unmountComponentAtNode(document.getElementById('example'))
}
render(){
return(
<div>
this.state.opacity}}>{this.props.content}
div>
)
}
}
ReactDOM.render('为什么不过节?'}/>,document.getElementById('example'))
//做一个跳转页面
<script src="../js/react.js">script>
<script src="../js/react-dom.js">script>
<script src="../js/babel.min.js">script>
<script src="https://cdn.bootcss.com/axios/0.16.2/axios.js">script>
<script type="text/babel">
class UserLastGist extends React.Component {
constructor (props) {
super(props)
this.state = {
url: null
}
}
componentDidMount () {
// 发送ajax请求
const url = `https://api.github.com/users/${this.props.username}/gists`
axios.get(url)
.then(response => {
console.log(response)
// 读取响应数据
//0索引位代表最后更新的网页内容
const url = response.data[0].html_url
// 更新状态
this.setState({url})
})
.catch(function (error) {
console.log('----', error);
})
}
render () {
const {url} = this.state
if(!url) {
return <h2>loading...h2>
} else {
return <p>{this.props.username}'s last gist is <a href={url}>herea> p>
}
}
}
UserLastGist.propTypes = {
username: React.PropTypes.string.isRequired
}
ReactDOM.render(<UserLastGist username="octocat"/>, document.getElementById('example'))
script>