1.属性和状态
1.属性props
- 含义:props = properties
- 属性:一个事物的性质与关系,属性往往是与生俱来的,无法自己改变的
- 属性的两种用法:
a). "?"中的内容可以是:字符串,对象{},数组{[1,2,3]},变量{var}
b). <Demo {...props} />
var props = { one : "123", two : "456" } - getDefaultProps : 设置默认属性 第一个调用
2.状态state
- 状态 :事务所处的状况
状况是由食物自行处理,不断变化的。父组件与子组件都无法改变他的状态。 - 状态的用法:
a). getInitialState : 初始化状态
b). setState : 更新状态
属性和状态相似点 :
a). 都是纯js对象,使用{}创建的对象
b). 都会触发render更新
c). 都具有确定性,给定相同的属性或者相同的状态,结果是相同的
属性和状态的区分: 组件在运行时需要修改的数据就是状态,所有的数据都可以变成状态
以下是例子
//demo1 :属性的第一种写法
<div id="demo1"></div>
<script type="text/babel">
var oDemo = document.getElementById("demo1"),
Demo = React.createClass({
render(){
return <div>{this.props.title}</div>
}
});
ReactDOM.render(<Demo title={"Demo"}/>, oDemo);
//this.props.title表示的就是title={"Demo"},因此在浏览器上会显示出Demo这个单词
</script>
//demo2 :属性的第二种写法
<div id="demo2"></div>
<script type="text/babel">
var oDemo = document.getElementById("demo2"),
Demo = React.createClass({
render(){
return (<div>
<div>{this.props.title}</div>
<a {...this.props}>{this.props.title}</a>
</div>)
{/*
...this.props
props提供的一个语法糖,可以将父组件中的全部属性复制给子组件,
如果是这个标签本身拥有的这个属性,则全部复制给子组件;反之没有效果
*/}
);
}
});
var props = {
title : "百度",
href : "http://www.baidu.com"
};
ReactDOM.render(<Demo {...props}/>, oDemo);
</script>
3.this.props.children属性
children没有与组件的属性一一对应,表示组件的所有子节点,一般用于列表。
例子
<div id="demo3"></div>
<script type="text/babel">
var oDemo = document.getElementById("demo3"),
List = React.createClass({
render(){
return (<ul>
{ /*
列表项的数量以及内容不确定,在创建模板的时候菜确定。
利用this.props.children从父组件获取需要的内容。
利用React.Children.map方法进行children的遍历。
用遍历的时候需要加{}。
map函数会返回值,存在child中。
*/
React.Children.map(this.props.children, function(child){
return <li>{child}</li>;
});
}
</ul>);
}
});
ReactDOM.render(<List>
<h1>百度</h1>
<a href="http://www.baidu.com">http://www.baidu.com</a>
</List>, oDemo);
</script>
demo3运行后html会变成如下:
<div id="demo3">
<ul data-reactroot="">
<li>
<h1>百度</h1>
</li>
<li>
<a href="http://www.baidu.com">http://www.baidu.com</a>
</li>
</ul>
</div>
状态state的例子
//demo4 state
<div id="demo4"></div>
<script type="text/babel">
var oDemo = document.getElementById("demo4"),
Demo = React.createClass({
//设置初始的状态 getInitialState
getInitialState(){
return {
// 这里的值可以是一个boolean,string,function
onOff : true;
};
},
handleClick(){
// 通过点击事件来修改状态值,原来的状态值需要使用this.state获取
this.setState({
//取反
onOff: !this.state.onOff
});
},
render(){
return (<div onClick={this.handleClick}>{this.state.onOff ? "data1":"data2"}</div>);
//当点击时,按照onOff属性的改变而改变值
}
)};
ReactDOM.render(<Demo />, oDemo);
</script>
小案例:本地时间的显示
//demo5
<div id="demo5"></div>
<script type="text/babel">
var oDemo = document.getElementById("demo5"),
Demo = React.createClass({
//设置默认的属性
getDefauleProps(){
return{
name : "现在的时间是:"
};
},
//设置初始的状态 getInitialState
getInitialState(){
return {
time: new Date().toLocaleTimeString();
};
},
change(){
// 在定时器中使用this.setState的时候需要将这个this变保存起来
var that = this;
setInterval(function(){
that.setState({
time: new Date().toLocaleTimeString();
});
},1000);
},
render(){
return (<div onClick={this.change()}>{this.props.name}{this.state.time}</div>);
}
)};
ReactDOM.render(<Demo name="北京时间: "/>, oDemo);
</script>
2.组件的生命周期(初始化阶段)
生命周期:组件的本质是状态机,输入确定,输出一定确定。 一个state对应一个render,状态转换的时候会触发不同的函数。
生命周期的三个阶段:
- 初始化阶段 : 设置初始的属性与状态
a). getDefaultProps: 设置初始的属性,只在第一次调用,实例之间共享引用。
b). getInitialState: 设置初始的状态。
c). componentWillMount: 组件将要加载,render之前最后一次修改状态的机会。
d). render: 只能访问this.props和this.state,只有一个顶层标签(组件),不允许修改状态和DOM输出。
e). componentDidMount: 成功render并渲染完成真实DOM之后出发,可以修改DOM,要操作DOM也必须在这个阶段完成。
例子
//demo1
<div id="demo6"></div>
<script type="text/babel">
var oDemo = document.getElementById("demo6"),
Demo = React.createClass({
//第一步:设置初始的属性,只执行一次
getDefaultProps(){
return {
name1: "一个盒子",
title: "box"
};
},
//第二步:设置初始的状态(可以将属性改成状态)
getInitialState(){
return {
name2: this.props.name1
};
},
//第三步:组件将要加载的时候,最后一次可以修改状态的机会
componentWillMount(){
this.setState({
name2: "最后一次修改机会"
});
//第三步中是无法获取到节点的
},
//第四步:render渲染
render(){
var styles = {
position:'absolute',
width: '100px',
height: '100px',
color: 'red',
background: 'lime'
};
return <div ref="box" style={styles}>{this.props.title}{this.state.name2}</div>;
},
//第五步:组件完成加载,只有在这一个阶段,才可以操作DOM节点
componentDidMount(){
var box = this.refs.box, //父级引用子级
timer = null,
n = 0;
box.onclick = function(){
var that = this;
timer = setInterval(function(){
n++;
that.style.left = n + "px";
},100);
};
}
});
ReactDOM.render(<Demo />, oDemo);
</script>
效果图: 点击后会慢慢往右移动
