特点
- 声明式设计
- 高效
- 灵活
- JSX
- 组件
- 单向数据流
第一个实例
<!--React的核心库-->
<script src="https://cdn.bootcss.com/react/15.6.1/react.js"></script>
<!--提供与DOM相关的功能-->
<script src="https://cdn.bootcss.com/react/15.6.1/react-dom.js"></script>
<!--将ES6代码转换为ES5代码-->
<script src="https://cdn.bootcss.com/babel-standalone/6.25.0/babel.js"></script>
<div id="box"></div>
<!--如果需要使用JSX,则<script>标签的type属性需要设置为text/babel-->
<script type="text/babel">
// render方法用于将模板转化为HTML语言,并插入指定的DOM节点
ReactDOM.render(
// 将h1标题插入id="box"的节点中
<h1>hello react</h1>,
document.getElementById('box')
);
</script>
JSX
<div id="box"></div>
<script type="text/babel">
ReactDOM.render(
<div>
<h1>hello world</h1>
<h2>hello react</h2>
{/*添加自定义属性需要使用data-前缀*/}
<p data-myattribute="somevalue">
my name is osoLife,i love react
</p>
</div>,
document.getElementById('box')
);
</script>
JS表达式
<div id="box"></div>
<script type="text/babel">
ReactDOM.render(
<div>
{/*表达式写在{}中*/}
<h1>{1+1}</h1>
</div>,
document.getElementById('box')
);
</script>
<!--在JSX中不能使用if else语句,但可以使用三元运算来替代-->
样式
<div id="box"></div>
<script type="text/babel">
var myStyle={
fontSize:50,
color:'#ccc'
};
ReactDOM.render(
<h1 style={myStyle}>React推荐使用内联样式</h1>,
document.getElementById('box')
);
</script>
数组
<!--JSX允许在模板中插入数组,数组会自动展开所有成员-->
<div id="box"></div>
<script type="text/babel">
var arr=[
<h1>hello world</h1>,
<p>hello react</p>
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById('box')
);
</script>
HTML标签&React组件
<!--要渲染HTML标签,只需在JSX里使用小写字母的标签名-->
<div id="box"></div>
<script type="text/babel">
// 在添加属性时,class属性需要写成className,for属性需要写成htmlFor,这是因为class和for是JS的保留字
var myDivElement=<div className="example" />;
ReactDOM.render(
myDivElement,
document.getElementById('box')
);
</script>
<!--要渲染React组件,只需创建一个大写字母开头的本地变量-->
组件
<!--将代码封装成一个组件,然后像插入HTML标签一样在网页中插入这个组件-->
<!--弃用的写法:ES5-->
<div id="box"></div>
<script type="text/babel">
// 创建一个名为HelloReact的组件
var HelloReact=React.createClass({
render:function () {
return <h1>hello react</h1>;
}
});
ReactDOM.render(
<HelloReact />,
document.getElementById('box')
);
</script>
<div id="box"></div>
<script type="text/babel">
// 通过this.props对象向组件中传递参数
var HelloReact=React.createClass({
render:function () {
return <h1>hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloReact name="react" />,
document.getElementById('box')
);
</script>
<!--推荐的写法:ES6-->
<div id="box"></div>
<script type="text/babel">
class HelloReact extends React.Component {
// 所有的组件类都必须有自己的render方法用于输出组件
render() {
return <h1>hello {this.props.name}</h1>;
}
}
ReactDOM.render(
<HelloReact name="react" />,
document.getElementById('box')
);
</script>
复合组件
<div id="box"></div>
<script type="text/babel">
class WebSite extends React.Component {
render() {
return (
<div>
<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="https://www.baidu.com"/>,
document.getElementById('box')
);
</script>
State(状态)
<!--方法一-->
<div id="box"></div>
<script type="text/babel">
class MyButton extends React.Component {
constructor(props) {
super(props);
this.handleClick=this.handleClick.bind(this);
this.state={
liked:false
}
}
handleClick(e) {
this.setState({liked:!this.state.liked});
}
render() {
var text=this.state.liked?'喜欢':'不喜欢';
return (
<p onClick={this.handleClick}>
你<b>{text}</b>我
</p>
);
}
}
ReactDOM.render(
<MyButton />,
document.getElementById('box')
);
</script>
<!--方法二-->
<div id="box"></div>
<script type="text/babel">
class MyButton extends React.Component {
state = {
liked:false
}
constructor(props) {
super(props);
this.handleClick=this.handleClick.bind(this);
}
handleClick(e) {
this.setState({liked:!this.state.liked});
}
render() {
var text=this.state.liked?'喜欢':'不喜欢';
return (
<p onClick={this.handleClick}>
你<b>{text}</b>我
</p>
);
}
}
ReactDOM.render(
<MyButton />,
document.getElementById('box')
);
</script>
Props
<!--可以把props看成是组件的配置属性,在调用这个组件时传入不同的属性来定制显示这个组件-->
<!--state和props主要的区别在于props是不可变的,而state可以根据与用户交互来改变,有些组件需要定义state来更新和修改数据,而子组件只能通过props来传递数据。-->
<div id="box"></div>
<script type="text/babel">
class HelloReact extends React.Component {
render() {
return <h1>Hello {this.props.name}</h1>;
}
}
ReactDOM.render(
<HelloReact name="React" />,
document.getElementById('box')
);
</script>
默认Props
<!--方法一-->
<div id="box"></div>
<script type="text/babel">
class HelloReact extends React.Component {
render() {
return <h1>Hello {this.props.name}</h1>;
}
// 组件内部使用static
static defaultProps={
name:'React'
}
}
ReactDOM.render(
<HelloReact />,
document.getElementById('box')
);
</script>
<!--方法二-->
<div id="box"></div>
<script type="text/babel">
class HelloReact extends React.Component {
render() {
return <h1>Hello {this.props.name}</h1>;
}
}
// 组件外部
HelloReact.defaultProps={
name:'React'
}
ReactDOM.render(
<HelloReact />,
document.getElementById('box')
);
</script>
State和Props
<!--在父组件中设置state,并通过在父组件上使用props将其传递到子组件上-->
<div id="box"></div>
<script type="text/babel">
class WebSite extends React.Component {
constructor(props) {
// 调用super()将props传递给React.Component
super(props);
// 初始化state的工作要在constructor中完成
this.state={
name:'百度',
site:'https://www.baidu.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 />,
document.getElementById('box')
);
</script>
Props验证
<div id="box"></div>
<script type="text/babel">
var title="Hello React";
class HelloReact extends React.Component {
render() {
return <h1>{this.props.title}</h1>;
}
}
HelloReact.propTypes={
title:React.PropTypes.string.isRequired
}
ReactDOM.render(
<HelloReact title={title} />,
document.getElementById('box')
);
</script>
<!--props-types的独立与react.PropTypes的弃用-->
<!--由于ES6类中只允许定义方法并不允许定义类属性,所以propTypes、getDefaultTypes、displayName还有contextType等组件属性都要放到类外面来赋值。-->
组件API
- 设置状态:setState
- 替换状态:replaceState
- 设置属性:setProps
- 替换属性:replaceProps
- 强制更新:forceUpdate
- 获取DOM节点:findDOMNode
- 判断组件挂载状态:isMounted
setState(设置状态)
<div id="box"></div>
<script type="text/babel">
class Counter extends React.Component {
constructor() {
super();
this.state={
clickCount:0
};
this.handleClick=this.handleClick.bind(this);
}
handleClick() {
this.setState(
function (state) {
return {
clickCount:state.clickCount+1
}
}
);
}
render() {
return (
<h2 onClick={this.handleClick}>点我!点击次数为:{this.state.clickCount}</h2>
);
}
}
ReactDOM.render(
<Counter />,
document.getElementById('box')
)
</script>
组件生命周期
三个状态:
Mounting:已插入真实DOM
Updating:正在被重新渲染
Unmounting:已移出真实DOM
方法:
componentWillMount
componentDidMount
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
componentDidUpdate
componentWillUnmount
componentDidMount示例
<!--通过componentDidMount方法设置一个定时器,每隔100毫秒重新设置组件的透明度,并重新渲染-->
<div id="box"></div>
<script type="text/babel">
class HelloReact extends React.Component {
constructor() {
super();
this.state={
opacity:1
};
}
componentDidMount() {
this.timer=setInterval(function () {
var opacity=this.state.opacity;
opacity-=.05;
if(opacity<0.1){
opacity=1;
}
this.setState({
opacity:opacity
});
}.bind(this),100);
}
render() {
return(
<div style={{opacity:this.state.opacity}}>
Hello {this.props.name}
</div>
)
}
}
ReactDOM.render (
<HelloReact name="osoLife" />,
document.getElementById('box')
);
</script>
<!--初始化state,setNewNumber用于更新state。所有生命周期在Content组件中-->
<div id="box"></div>
<script type="text/babel">
class Button extends React.Component {
constructor() {
super();
this.state={
data:0
};
this.setNewNumber=this.setNewNumber.bind(this);
}
setNewNumber() {
this.setState({
data:this.state.data+1
});
}
render() {
return(
<div>
<button onClick={this.setNewNumber}>increament</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 />,
document.getElementById('box')
)
</script>
AJAX(待续)
表单与事件
<div id="box"></div>
<script type="text/babel">
class HelloReact extends React.Component {
constructor() {
super();
this.state={
value:'hello osoLife'
};
this.handleChange=this.handleChange.bind(this);
}
handleChange(event) {
this.setState({
value:event.target.value
});
}
render() {
var value=this.state.value;
return (
<div>
<input type="text" value={value} onChange={this.handleChange} />
<h4>{value}</h4>
</div>
);
}
}
ReactDOM.render(
<HelloReact />,
document.getElementById('box')
)
</script>
<div id="box"></div>
<script type="text/babel">
class Content extends React.Component {
render() {
return (
<div>
<input type="text" value={this.props.myDataProp} onChange={this.props.updateStateProp} />
<h4>{this.props.myDataProp}</h4>
</div>
);
}
}
class HelloReact extends React.Component {
constructor() {
super();
this.state={
value:'hello osoLife'
};
this.handleChange=this.handleChange.bind(this);
}
handleChange(event) {
this.setState({
value:event.target.value
});
}
render() {
var value=this.state.value;
return (
<div>
<Content myDataProp={value} updateStateProp={this.handleChange}>
</Content>
</div>
);
}
}
ReactDOM.render(
<HelloReact />,
document.getElementById('box')
);
</script>
事件
<div id="box"></div>
<script type="text/babel">
class HelloReact extends React.Component {
constructor() {
super();
this.state={
value:'hello world'
};
this.handleClick=this.handleClick.bind(this);
}
handleClick() {
this.setState({
value:'hello osoLife'
});
}
render() {
var value=this.state.value;
return (
<div>
<button onClick={this.handleClick}>click me</button>
<h4>{value}</h4>
</div>
);
}
}
ReactDOM.render(
<HelloReact />,
document.getElementById('box')
);
</script>
<div id="box"></div>
<script type="text/babel">
class Content extends React.Component {
render() {
return (
<div>
<button onClick={this.props.updateStateProp}>click me</button>
<h4>{this.props.myDataProp}</h4>
</div>
);
}
}
class HelloReact extends React.Component {
constructor() {
super();
this.state={
value:'hello osoLife'
};
this.handleClick=this.handleClick.bind(this);
}
handleClick() {
this.setState({
value:'hello world'
});
}
render() {
var value=this.state.value;
return (
<div>
<Content myDataProp={value} updateStateProp={this.handleClick}>
</Content>
</div>
);
}
}
ReactDOM.render(
<HelloReact />,
document.getElementById('box')
);
</script>
Refs
<!--React支持一种非常特殊的属性Ref,可以用来绑定到render()输出的任何组件上。在其它代码中,通过this.refs获取支撑实例-->
<div id="box"></div>
<script type="text/babel">
class MyComponent extends React.Component {
constructor() {
super();
this.handleClick=this.handleClick.bind(this);
}
handleClick() {
this.refs.myInput.focus();
}
render() {
return (
<div>
<input type="text" ref="myInput" />
<button onClick={this.handleClick}>点击输入框获得焦点</button>
</div>
);
}
}
ReactDOM.render(
<MyComponent />,
document.getElementById('box')
);
</script>
结束语
如果喜欢本文,记得点赞并加关注哟。
网友评论