一、虚拟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 . statereturn < h1 onClick= { this . changeWeather} > 今天天气很{ isHot ? '炎热' : '寒冷' } ,{ wind} < / h1> } changeWeather ( ) { console. log ( 'changeWeather' ) const isHot = this . state. isHotthis . 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 . statereturn < h1 onClick= { this . changeWeather} > 今天天气很{ isHot ? '炎热' : '寒冷' } ,{ wind} < / h1> } changeWeather = ( ) => { const isHot = this . state. isHotthis . 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 . propsreturn ( < 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 . propsreturn ( < 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} = propsreturn ( < 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>