先学习react基础,后期利用create-react-app脚手架生成开发环境
1)安装
可以直接去React官网或者github直接下载
案例中直接使用cdn库
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
react.min.js是react基础库、react-dom.min.js是提供与 DOM 相关的功能、babel.min.js是提供ES6语法解析
2)HTML 模板
使用 React 的网页源码,结构大致如下。
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
// ** Our code goes here! **
</script>
</body>
</html>
这里注意的是script的标签type属性值不在是’text/javascript’而是“text/babel”了,这是因为 React 独有的 JSX 语法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type=“text/babel” 。
3)render函数
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。
案例分析:这个例子是讲一个h1标签插入到id为example节点上。
4)JSX 语法
所谓的jsx语法就是HTML语法直接写在javascript中,不用添加任何引号,它允许HTML与js混写,当需要使用js的时候我们只需要"{把js语法括起来}"
<div id="example"></div>
var names = ['小明','小红','小兰'];
ReactDOM.render(
<div>
{
names.map((name,index)=>{
return <div data-index={index}>{name}</div>
})
}
</div>,
document.getElementById('example')
)
5)组件
组件化开发,相信许多的前端儿都听过,组件的最大好处就是方便复用,在React框架中也是有组件这一说
组件的方式是React.createClass()
<div id="example"></div>
let Hi = React.createClass({
render : function(){
return <div>hello,word</div>
}
});
ReactDOM.render(
<Hi />,
document.getElementById('example')
)
1、上面代码中,变量 Hi 就是一个组件类。模板插入 时,会自动生成 Hi 的一个实例(下文的"组件"都指组件类的实例)。所有组件类都必须有自己的 render 方法,用于输出组件。
2、注意,组件类的第一个字母必须大写,否则会报错,比如Hi不能写成hi。另外,组件类只能包含一个顶层标签,否则也会报错。
let Hi = React.createClass({
render : function(){
return <div>hello,word</div><div>hello,世界</div>
}
});
这种情况就会报错,因为组件中只能由一层顶级标签
5-1、父子通信
this.props.属性名称
<div id="example"></div>
let Hi = React.createClass({
render : function(){
return <div>hello,{this.props.name}</div>
}
});
ReactDOM.render(
<Hi name="小明 "/>,
document.getElementById('example')
)
6)this.props.children
var NotesList = React.createClass({
render: function() {
return (
<ol>
{
React.Children.map(this.props.children, function (child) {
return <li>{child}</li>;
})
}
</ol>
);
}
});
ReactDOM.render(
<NotesList>
<span>hello</span>
<span>world</span>
</NotesList>,
document.body
);
上面代码的 NoteList 组件有两个 span 子节点,它们都可以通过 this.props.children 读取
这里需要注意, this.props.children
的值有三种可能:如果当前组件没有子节点,它就是 undefined
;如果有一个子节点,数据类型是 object
;如果有多个子节点,数据类型就是 array
。所以,处理 this.props.children
的时候要小心。
React 提供一个工具方法 React.Children
来处理 this.props.children
。我们可以用 React.Children.map
来遍历子节点,而不用担心 this.props.children
的数据类型是 undefined
还是 object
。更多的 React.Children
的方法,请参考官方文档。
7)PropTypes
PropTypes规定父子通信的数据类型
var MyTitle = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired, //字符串类型 而且此属性是必传的
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
var data = 123;
ReactDOM.render(
<MyTitle title={data} />
)
这个样就会报错了 因为data是number属性
8)获取真实的DOM节点
组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。
但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 ref
属性
let Hand = React.createClass({
alertfn(){
alert(this.refs.istest.getAttribute('name'))
},
render : function(){
return <div>
<div name="小明" ref="istest"></div>
<button onClick={this.alertfn}>测试</button>
</div>
}
});
ReactDOM.render(
<Hand />,
document.body
)
在按钮点击的时候获取div上的name属性利用
refs
获取DOM,顺带学习了事件的获取
React 组件支持很多事件,除了Click
事件以外,还有KeyDown
、Copy
、Scroll
等,完整的事件清单请查看官方文档。
9)this.state
组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI
let ChangeState = React.createClass({
getInitialState(){
return {color:false};
},
changeColor(){
this.setState({color : !this.state.color})
},
render(){
var c = this.state.color ? 'blue' : 'yellow';
return <div>
<div style={{height:"30px",background:c}}></div>
<button type="button" onClick={this.changeColor}>点击</button>
</div>
}
});
ReactDOM.render(
<ChangeState />,
document.body
)
此效果通过点击事件改变color的状态从而达到改变背景色的需求
ChangeState
组件中 getInitialState
方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state
属性读取。当用户点击组件,导致状态变化,this.setState
方法就修改状态值,每次修改以后,自动调用 this.render
方法,再次渲染组件。
由于 this.props
和 this.state
都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props
表示那些一旦定义,就不再改变的特性,而 this.state
是会随着用户互动而产生变化的特性。
10)表单
vue框架有一个v-model双向数据绑定,而react并没有,通过监听inputchange事件并绑定state就可实现v-model同效果
var Myform = React.createClass({
getInitialState(){
return {message : ''}
},
changetext(ev){
this.setState({message:ev.target.value});
},
render(){
return <div>
<input type="text" value={this.state.message} onChange={this.changetext} />
<p>{this.state.message}</p>
</div>
}
});
ReactDOM.render(
<Myform />,
document.body
)
上面代码中,文本输入框的值,不能用 this.props.value
读取,而要定义一个 onChange
事件的回调函数,通过 event.target.value
读取用户输入的值。textarea
元素、select
元素、radio
元素都属于这种情况,更多介绍请参考官方文档。
11)组件的生命周期
组件的生命周期分成三个状态:
- 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):组件判断是否重新渲染时调用
这些方法的详细说明,可以参考官方文档
let Hi = React.createClass({
getInitialState(){
console.log(1)
return this.state = {
color : 'red'
}
},
componentWillMount(){
console.log(2)
},
componentDidMount(){
console.log(3)
},
componentWillUnmount(){
console.log(4)
},
render(){
console.log(5)
return (
<div>测试react的生命周期{this.state.color}</div>
)
}
});
ReactDOM.render(
<Hi />,
document.body
)
let Hi = React.createClass({
getInitialState(){
console.log('------初始化state状态------')
return this.state = {
test : '生命周期详解 --十年'
}
},
componentWillMount(){
console.log('------挂载前------')
},
componentDidMount(){
console.log('------挂载结束------')
},
componentWillUnmount(){
console.log('------组件销毁------')
},
render(){
console.log('------执行render函数------')
return (
<div>{this.state.test}</div>
)
}
})
let open = true;
window.addEventListener('click',()=>{
if(open){
ReactDOM.render(
<Hi />,
document.body
)
}else{
ReactDOM.render(
<div>更改组件</div>,
document.body
)
}
open = !open
})
案列解析,这次利用点击事件替换
React
的组件
12)ES6中的React
class Hi extends React.Component {
constructor(props){
console.log('初始化state')
super(props);
this.seting = {
color : '你好,ES6语法'
}
}
componentWillMount(){
console.log('挂在前')
}
componentDidMount(){
console.log('挂载结束')
}
componentWillUnmount(){
console.log('销毁前')
}
render(){
console.log('render函数')
return(
<div>{this.seting.color}</div>
)
}
};
ReactDOM.render(
<Hi />,
document.body
)
13)一次代码让你彻底理解React
class Hi extends React.Component {
constructor(props){
super(props)
this.state = {
color : 'red',
fontSize : '40px'
}
console.log('初始化state')
}
componentWillMount(){
console.log('组件挂载前的钩子函数')
}
componentDidMount(){
console.log('组件挂载后的钩子函数')
}
componentWillUnmount(){
console.log('组件销毁')
}
render(){
console.log('render函数')
return (
<div style={this.state}>
<p>初试React</p>
</div>
)
}
}
ReactDOM.render(
<Hi />,
document.body
)
参开文章阮一峰react