一、初识React
1.特点
- 基于组件,组件里面有自己的state,用组件来做复杂的UI;
- 用JavaScript语言逻辑而不是模板;
- 当你改变数据的时候它可以快速更新;
- React不是一个完整的MVC,MVVM框架;
- React跟Web Components不冲突;
- React的特点是“轻”,渲染、响应非常快;
- 组件化的开发思路,高度可重用。
2.看看一个简单的组件例子
react组件用render()方法传入数据和返回。下面这个例子用了一种长得像XML的语法——jsx。输入的数据可以通过render()
的this.props
来传进组件。
class HelloMessage extends React.Compontent {
render() {
return <div>Hello {this.props.name}</div>;
}
}
ReactDOM.render(<HelloMessage name="Jane" />,mountNode);
二、各种例子
1. HTML模板
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="script/react.js"></script>
<script src="script/react-dom.js"></script>
<script src="script/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
//这里写你的react代码,使用jsx语法
</script>
</body>
</html>
body内的<script>标签,是写入react代码,由于react独有的jsx语法,跟js不兼容,所以使用jsx的地方,type类型为type="text/babel"。
head标签内引用了三个库:react.js 、react-dom.js 和 Browser.js,它们必须首先加载。其中,react.js 是 React 的核心库,react-dom.js 是提供与 DOM 相关的功能,Browser.js 的作用是将 JSX 语法转为 JavaScript 语法,这一步很消耗时间,实际上线的时候,应该将它放到服务器完成。
eg:将一个 h1 标题,插入 example 节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="script/react.js"></script>
<script src="script/react-dom.js"></script>
<script src="script/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>
运行结果截图:
- ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。render()方法的第一个参数是你要插入的模板,第二个参数是指定插入的节点的位置。
2. 遍历一个数组插入节点中
<body>
<div id="example"></div>
<script type="text/babel">
var names = ['Mingming','XiaoHong','Baby'];
ReactDOM.render(
<div>
{
names.map(function(name) {
return <h1>Hello {name} !</h1>
})
}
</div>,
document.getElementById("example"));
</script>
</body>
- 对names中的每一个元素都执行一个匿名函数,这个匿名函数的参数name就是当前的遍历到的names的某一个元素,用这个元素替换“Hello {name}”的name位置,然后返回这个“h1”元素,将每一个返回的h1元素都插入到由document.getElementById("example")指定的节点位置,即插入到id值为“example”的div节点中。
3. 插入JavaScript变量
<body>
<div id="example"></div>
<script type="text/babel">
var arr = [
<h1>I am Array1!</h1>,
<h1>I am Array2!</h1>
]
ReactDOM.render(
<div>{arr}</div>,
document.getElementById("example"));
</script>
</body>
4. 封装组件
<body>
<div id="example"></div>
<script type="text/babel">
var HelloMessage = React.createClass({
render:function() {
return <h1>Hello {this.props.name} !</h1>
}
});
ReactDOM.render(<HelloMessage name="Qiapi"/>,document.getElementById("example"));
</script>
</body>
- 格式:
var 组件名(首字母一定大写) = React.createClass({
render:function() {
return 返回的模板
}
});
-
this.props.name
传入参数 - 组件类只能包含一个顶层标签,即return 只能返回一个标签,不可以像下面这样的return:
return <h1>haha</h1><p>hehe</p>//这是错误的
- 添加组件属性,有一个地方需要注意,就是 class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。
5. this.props.children
<body>
<div id="example"></div>
<script type="text/babel">
var NoteList = React.createClass({
render:function() {
return (
<ol>
{
React.Children.map(this.props.children,function(child) {
return <li>{child}</li>
})
}
</ol>
)
}
});
ReactDOM.render(
<NoteList>
<span>Hello</span>
<span>World</span>
</NoteList>,
document.getElementById("example"));
</script>
</body>
6. PropsType
<body>
<div id="example"></div>
<script type="text/babel">
var HelloMessage = React.createClass({
propTypes:{
title:React.PropTypes.string.isRequired,//这句的意思是要求title的属性是string
},
render:function() {
return <h1>I say: {this.props.title}</h1>
}
});
ReactDOM.render(
<HelloMessage title="Here is a title"/>,
document.getElementById("example"));
</script>
</body>
- propTypes用来设置属性类型,上例中设置了string类型,所以在为组件设置title值的时候必须为string类型,如果将其设置为数字,则会报错,例如:
可以这样:
- 注意不要直接把123写到title里:
- 设置默认的title值:
7.refs 和 this.state
<body>
<div id="example"></div>
<script type="text/babel">
var MyComponent = React.createClass({
getInitialState:function() {
return({text:''});
},
handleClick:function() {
this.setState({text:this.refs.myTextInput.value});
},
render:function() {
return (
<div>
<input type="text" ref="myTextInput"/>
<input type="button" onClick={this.handleClick} value="click me!" />
<p>{this.state.text}</p>
</div>
)
}
})
ReactDOM.render(
<MyComponent/>,document.getElementById("example"));
</script>
</body>
- getInitialState:设置初始的state值;
- handleClick:自定义的一个方法,用来处理点击事件。为按钮设置了onClick={this.handleClick}后,当点击按钮时就会调用这个方法,进行相应的处理;
- this.setState():设置this.state;
- this.refs.myTextInput:ref值为myTextInput的元素;
- 动态的数据不用 this.props 获取,用 this.state;
8. 表单
<body>
<div id="example"></div>
<script type="text/babel">
var Input = React.createClass({
getInitialState: function() {
return {value:'hello'};
},
handleChange: function(event) {
this.setState({value:event.target.value});
},
render:function() {
var value = this.state.value;
return (
<div>
<input value={value} type="text" onChange={this.handleChange} />
<p>{value}</p>
</div>
);
}
});
ReactDOM.render(<Input/>,document.getElementById("example"));
</script>
</body>
三、组件的生命周期
组件的生命周期分成三个状态:
Mounting:已插入真实 DOM
Updating:正在被重新渲染
Unmounting:已移出真实 DOM
React 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数。
componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()
React 还提供两种特殊状态的处理函数:
componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用
<body>
<div id="example"></div>
<script type="text/babel">
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.getElementById("example"));
</script>
</body>