一、虚拟DOM和真实DOM
< script type= "text/babel" >
const VDOM = (
< h1 id= "title" >
< span> Hello, React! < / span>
< / h1>
)
ReactDOM. render ( VDOM , document. getElementById ( 'box' ) )
const TDOM = document. getElementById ( 'test' )
console. log ( '虚拟DOM' , VDOM )
console. log ( '真实DOM' , TDOM )
debugger ;
< / script>
关于虚拟DOM:
本质是Object对象(一般对象) 虚拟DOM比较“轻”(属性和方法少),真实DOM比较“重”(属性和方法多),因为虚拟DOM是React内部在用,无需真实DOM上那么多属性 虚拟DOM最终都会被React转换为真实DOM,最终呈现在页面。
二、jsx的语法规则
定义虚拟DOM时,不要用引号 标签中混入js表达式时,使用{} 样式的类名指定不能用class,要使用className,因为要与es6中的关键字类(class)做区分 内联样式,要使用{{key:value}}的形式去写,外层{}表示里边的内容为js,内层{}表示对象 只能有一个根标签 标签必须闭合 标签首字母: 1)首字母小写开头,则将该标签转为html中的同名元素,若html中无与之对应的同名元素,则报红色警告 2)首字母大写开头,react会去渲染对应的组件,若组件没有定义,则报错。
< script type= "text/babel" >
const myId = 'container'
const myData = 'Hello, React'
const VDOM = (
< div>
< h1 className= "title" id= { myId} >
< span style= { { color : 'white' } } > { myData} < / span>
< / h1>
< h1 className= "title" id= { myId+ '2' } >
< span style= { { color : 'white' } } > { myData} < / span>
< / h1>
< good> 222 < / good>
< / div>
)
ReactDOM. render ( VDOM , document. getElementById ( 'box' ) )
< / script>
三、组件实例的三大属性
state
< script type= "text/babel" >
class Weather extends React. Component {
constructor ( props ) {
console. log ( 'constructor' )
super ( props)
this . state = { isHot : false , wind : '微风' }
this . changeWeather = this . changeWeather . bind ( this )
}
render ( ) {
console. log ( 'render' )
let { isHot, wind} = this . state
return < h1 onClick= { this . changeWeather} > 今天天气很{ isHot ? '炎热' : '寒冷' } ,{ wind} < / h1>
}
changeWeather ( ) {
console. log ( 'changeWeather' )
const isHot = this . state. isHot
this . setState ( { isHot : ! isHot} )
}
}
ReactDOM. render ( < Weather/ > , document. getElementById ( 'box' ) )
< / script>
简写方式
< script type= "text/babel" >
class Weather extends React. Component {
state = { isHot : false , wind : '微风' }
render ( ) {
let { isHot, wind} = this . state
return < h1 onClick= { this . changeWeather} > 今天天气很{ isHot ? '炎热' : '寒冷' } ,{ wind} < / h1>
}
changeWeather = ( ) => {
const isHot = this . state. isHot
this . setState ( { isHot : ! isHot} )
}
}
ReactDOM. render ( < Weather/ > , document. getElementById ( 'box' ) )
< / script>
props
< script type= "text/babel" >
class Person extends React. Component {
render ( ) {
const { name, age, gender} = this . props
return (
< ul>
< li> 姓名:{ name} < / li>
< li> 性别:{ age} < / li>
< li> 年龄:{ gender} < / li>
< / ul>
)
}
}
ReactDOM. render ( < Person name= "tom" age= "28" gender= "男" / > , document. getElementById ( 'box1' ) )
const p = { name : 'daisy' , age : '21' , gender : "女" }
ReactDOM. render ( < Person { ... p} / > , document. getElementById ( 'box2' ) )
< / script>
简写方式
< script type= "text/babel" >
class Person extends React. Component {
static propTypes = {
name : PropTypes. string. isRequired,
age : PropTypes. number,
gender : PropTypes. string,
}
static defaultProps= {
age : 10 ,
gender : '男'
}
render ( ) {
const { name, age, gender} = this . props
return (
< ul>
< li> 姓名:{ name} < / li>
< li> 年龄:{ age + 1 } < / li>
< li> 性别:{ gender} < / li>
< / ul>
)
}
}
ReactDOM. render ( < Person name= "tom" / > , document. getElementById ( 'box1' ) )
< / script>
函数式组件使用props
< script type= "text/babel" >
function Person ( props ) {
const { name, age, gender} = props
return (
< ul>
< li> 姓名:{ name} < / li>
< li> 年龄:{ age + 1 } < / li>
< li> 性别:{ gender} < / li>
< / ul>
)
}
Person. propTypes = {
name : PropTypes. string. isRequired,
age : PropTypes. number,
gender : PropTypes. string,
}
Person. defaultProps= {
age : 10 ,
gender : '男'
}
ReactDOM. render ( < Person name= "tom" / > , document. getElementById ( 'box1' ) )
< / script>
ref
< script type= "text/babel" >
class Demo extends React. Component {
myRef = React. createRef ( )
myRef2 = React. createRef ( )
showData = ( ) => {
alert ( this . myRef. current. value)
}
showData2 = ( ) => {
alert ( this . myRef2. current. value)
}
render ( ) {
return (
< div>
< input ref= { this . myRef} type= "text" placeholder= "点击按钮提示数据" / > & nbsp;
< button onClick= { this . showData} > 点我提示左侧数据< / button> & nbsp;
< input ref= { this . myRef2} type= "text" placeholder= "失去焦点提示数据" onBlur= { this . showData2} / >
< / div>
)
}
}
ReactDOM. render ( < Demo/ > , document. getElementById ( 'box' ) )
< / script>
四、事件处理
< script type= "text/babel" >
class Demo extends React. Component {
myRef = React. createRef ( )
myRef2 = React. createRef ( )
showData = ( ) => {
alert ( this . myRef. current. value)
}
showData2 = ( event ) => {
alert ( event. target. value)
}
render ( ) {
return (
< div>
< input ref= { this . myRef} type= "text" placeholder= "点击按钮提示数据" / > & nbsp;
< button onClick= { this . showData} > 点我提示左侧数据< / button> & nbsp;
< input type= "text" placeholder= "失去焦点提示数据" onBlur= { this . showData2} / >
< / div>
)
}
}
ReactDOM. render ( < Demo/ > , document. getElementById ( 'box' ) )
< / script>
事件处理总结:
通过onXxx属性指定事件处理函数(注意大小写) a)React使用的是自定义(合成)事件,而不是使用的原生DOM事件 ----为了更好的兼容性 b)React中的事件是通过事件委托方式处理的(委托给组件最外层的元素) ---- 为了更高效 通过event.target得到发生事件的DOM元素对象 ---- 不要过度使用ref
五、组件的生命周期(详细代码在下一篇笔记)
旧版与新版对比图示:
附:使用html学习React基础代码
< ! DOCTYPE html>
< html lang= "en" >
< head>
< meta charset= "UTF-8" >
< meta http- equiv= "X-UA-Compatible" content= "IE=edge" >
< meta name= "viewport" content= "width=device-width, initial-scale=1.0" >
< title> demo< / title>
< / head>
< body>
< ! -- 准备好一个容器 -- >
< div id= "box" > < / div>
< ! -- 引入react核心库 -- >
< script type= "text/javascript" src= "https://unpkg.com/react@16/umd/react.development.js" > < / script>
< ! -- 引入react扩展库 -- >
< script type= "text/javascript" src= "https://unpkg.com/react-dom@16/umd/react-dom.development.js" > < / script>
< ! -- 引入babel,用于将jsx转换为js -- >
< script type= "text/javascript" src= "https://unpkg.com/@babel/standalone/babel.min.js" > < / script>
< ! -- 引入prop- types,用于对组件标签的限制 -- >
< script type= "text/javascript" src= "../../../js/prop-types/prop-types.js" > < / script>
< script type= "text/babel" >
< / script>
< / body>
< / html>