react简介
react是由Fecebook开发的UI库,它的核心思想开发reactJS的组件可以重复调用,易于维护;每个组件有独立的状态,在状态发生改变时UI重新渲染。目前Fecebook开发的UI库有两种:开发web app的UI库reactJS和移动端开发UI库的react native。
利用codepen 学习react
codepen是一个在线前端编辑器,可以在线调试显示demo。codepen由三部分组成html,css,js,根据demo的需求将html,css,js的内容输入对应编辑框中,可在页面显示demo。
react是通过babel编译成js代码,codepen提供两个在线的编译库:
有关更多codepen的功能可以登录codepen网址:https://codepen.io/pen学习 。
reactJS的hello word
所有的demo都在codepen中实现,首先看一个hello word的实例:
html代码:
js代码:
var helloWord= Hello Word!
;
ReactDOM.render(
helloWord,
document.getElementById('root')
);
ReactDOM.render函数通过getElementById获取节点,将html元素输出该节点上。
JSX
react使用JSX标签渲染组件,JSX标签是js与html的混搭。最终JSX会被编译成js。在codepen的js编辑器中输入JSX事例如下:
function Welcome(){
return Hello Word!
;
};
ReactDOM.render(
,
document.getElementById('root')
);
JSX标签名称首字母必须是大写。标签可以添加属性,js代码,重复调用。
function Welcome(props){
return Hello , {props.name}
};
function App(){
return (
)
};
ReactDOM.render(
,
document.getElementById('root')
);
虚拟DOM
react有一个重要的概念:虚拟DOM,虚拟DOM主要是解决提高元素的渲染速度。虚拟DOM本质是将xml标签树结构保存在内存中,在组件状态发生改变后,通过diff算法快速对旧树和新树对比定位发生改变的组件节点,patch方法在内存中重新渲染该节点,最后输出到真实的DOM上。
reactJS组件
reactJs组件主要由状态,事件,生命周期,元素渲染组成。下面逐个详细分析。
组件创建
es6语法创建组件,继承React的Component。
class Welcome extends React.Component{
render(){
return Hello Word!
}
}
ReactDOM.render(
,
document.getElementById('root')
);
props && propTypes
props
props是一个对象,在组件中要获取外部传递的数据,函数等,通过props获取。props在组件内部不能修改,是只读属性。
const user={
name:'LiMing',
age:'23'
}
function App(props){
return (
Hello,{props.name}
age:{props.age}
)
}
ReactDOM.render(
,
document.getElementById('root')
);
propTypes
props的属性可以是字符串,对象,数字,函数等等。在使用propTypes定义属性类型,并且验证属性类型是否正确。
import PropTypes from 'prop-types';
class App extends React.Component {
render() {
return (
Hello,{this.props.name}
);
}
}
App.propTypes = {
name: PropTypes.string
};
ReactDOM.render(
,
document.getElementById('root')
);
⚠️需要引入prop-types库。codepen的在线库没有,所以在codepen中无法在线使用。
state
react的组件可以独立重复调用,state存储组件内部能够改变组件状态的对象。
class App extends React.Component{
constructor(props){
super(props);
this.state={
name:''
}
}
handleChange(e){
this.setState({name:e.target.value});
}
handleClick(e){
alert(this.state.name);
e.prevDefault();
}
render(){
return (
this.handleChange(e)} />
this.handleClick(e)} />
)
}
}
ReactDOM.render(
,
document.getElementById('root')
);
在输入框中输入内容时,onChange函数调用this.setState修改name的值。点击ok按钮,提示框显示文本框内容。prevDefault跳出当前函数,与js中的return false作用相同。
渲染
1)在react组件内部使用render渲染当前组件。
class App extends React.Component{
render(){
return(
Hello,{this.props.name}
Welcome here!
)
}
}
ReactDOM.render(
,
document.getElementById('root')
);
react组件只有一个根节点。一般return后面用“(”和“)”将渲染内容包起来,这样避免标签后面加“;”,编译后冲突。
2) 条件渲染
在react组件中,可以使用js的if或者条件判断当前状态的渲染内容。
function App(props)
{
if(props.isLogged){
return Welcome!
;
}
return Please sign up!
;
}
ReactDOM.render(
,
document.getElementById("root")
);
在react组件,将当前状态的渲染元素赋值给变量,在渲染时直接输出元素变量。元素变量的值不会被更改。
function Sign(){
return Please sign up!
;
}
function Logined(){
return Welcome!
;
}
class App extends React.Component {
render(){
const isLogined = this.props.isLogined;
let element;
if(isLogined){
element =
}else{
element =
}
return (
{element}
)
}
}
ReactDOM.render(
,
document.getElementById("root")
);
用let声明元素变量,react组件绝大部分变量都是不变即只读变量,所以基本用const声明。
三目函数
function App(props)
{
const isLogged= props.isLogged;
return isLogged?Welcome!
:Please sign up!
;
}
ReactDOM.render(
,
document.getElementById("root")
);
与运算和表达式:
function App(props)
{
const name= props.name;
return (
Welcome!
{name.length>0 &&
Hello,{name}
}
)
}
ReactDOM.render(
document.getElementById("root")
);
true && expression 运算结果返回expression,false && expression运算结果返回false。
事件
在构造器中初始化属性绑定this,如果this没有绑定,不会调onClick事件,函数则无效。
class App extends React.Component{
constructor(props){
super(props);
this.state={isShow:true};
this.showHandle = this.showHandle.bind(this);
this.hindHandle = this.hindHandle.bind(this);
}
showHandle(){
this.setState({isShow:true})
}
hindHandle(){
this.setState({isShow:false})
}
render(){
const isShow = this.state.isShow;
return(
Please active button!
{isShow?
:
)
}
}
ReactDOM.render(
,
document.getElementById('root')
);
事件名称使用驼峰命名法;在事件属性初始化绑定this时,如果是多个参数this是显式,其他参数是隐式传递。
使用箭头函数绑定如下:
class App extends React.Component{
constructor(props){
super(props);
this.state={isShow:true};
}
showHandle(){
this.setState({isShow:true})
}
hindHandle(){
this.setState({isShow:false})
}
render(){
const isShow = this.state.isShow;
return(
Please active button!
{isShow?
this.hindHandle()} />
:
this.showHandle()} />
)
}
}
ReactDOM.render(
,
document.getElementById('root')
);
使用箭头函数是显式的传递参数(e)=>this.showHandle(e),e是事件对象,有多个参数时e在最后。
生命周期
react组件自顶向下瀑布流加载或者单向数据加载,在加载过程不同状态调用不同函数。react内部提供了挂载和卸载两种勾子,如下:
class Clock extends React.Component{
constructor(props){
super(props);
this.state={date:new Date()}
}
componentDidMount(){
this.timer = setInterval(()=>this.tick(),1000);
}
componentWillUnmount(){
clearInterval(this.timer);
}
tick(){
this.setState({
date:new Date()
})
}
render(){
return(
It is clock!
{this.state.date.toLocaleTimeString()}
)
}
}
ReactDOM.render(
,
document.getElementById('root')
);
react组件三种状态:已插入真实Dom种,正在渲染,已移除真实DOM,5种处理函数,will是进入状态前调用函数,did是进入状态后调用函数:
componentWillMount:在组件挂载前调用一次。
componentDidMount:在组件挂载后调用一次。
componentWillUpdate :组件接受新的props或state更新都会调用,在初始化时不调用。
componentDidUpdate:在组件render后,state更新会调用,在初始化时不调用。
componentWillUnmount:在组件卸载时调用一次。
还有2种特殊函数:
componentRecevieProps(prveProps):已经加载组件接受新的参数时调用,prveProps父组件在调用render时候,调子组件传递的参数。
showComponentUpdate:判断组件是否重新渲染调用,返回true,调用componentWillUpdate。
refs
react组件通过虚拟Dom操作,那么需要操作真实Dom怎么办呢?react提供了ref属性,通过ref属性接受回调函数。
class App extends React.Component{
constructor(props){
super(props);
this.handleOk=this.handleOk.bind(this);
}
handleOk(){
alert(this.textInput.value);
}
render(){
return(
this.textInput=input} />
)
}
}
ReactDOM.render(
,
document.getElementById('root')
);
refs主要用于定位焦点,文本框选择,与第三方库集成等。