初识react
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./base/react.min.js"></script>
<!-- 提供react 对象 -->
<script src="./base/react-dom.min.js"></script>
<!-- 操作dom 更新-->
<script src='./base/browser.min.js'></script>
<!-- 帮助浏览器解析jsx语法 -->
</head>
<body>
<div id="app">
</div>
<script type="text/babel">//'text/babel' 告知浏览器 该范围内有jsx 需要用browser 库解析
// 创建的组件是虚拟dom
// 将虚拟dom 渲染为真实dom
// React中的组件首字母必须大写
// React 同样将组件名当成标签名使用
// JS代码中写标签 浏览器解析不了 jsx javascript xhtml(严格模式html)
// jsx 让我们可以在js中写标签
// jsx 就是一个语法糖 直接写标签形成虚拟dom
let Yinxm = React.createClass({// 通过react 对象下createClass 方法创建一个组件
getInitialState(){
//state需要通过 getInitialState 进行初始化使用 { 变量 表达式}
return{
name:'殷乡梅'
}
},
render(){ // render 函数 内部返回一个jsx - 对比模板引擎
console.log(this);//当前组件
let {name} = this,state
return(// jsx 必须只有一个根元素,标签必须闭合
<h1>Hi,sunny
{name}
</h1>
)
}
})
// ReactDOM.render(<Yinxm></Yinxm>,document.getElementById('app'))
ReactDOM.render(<Yinxm/>,app)//简写
// ReactDOM render 方法 参数1 要渲染的组件 参数2表示该 组件挂载到哪一个dom元素
</script>
</body>
</html>
- vue中 数据本身来源2种
props 父组件传递的
data 组件本身的- React 本身的数据来源 2中
props 组件传递的 只能用不能改
state 组件自己的 可以修改
数据承载 - 单向数据流
- props 从组件外部传递而来 在使用的组件中只能使用不能修改
- state 组件内部的数据 可以修改
- 数组 react 将数组的每一项进行拆分渲染
- 对象 react 不能直接绑定对象
注释 - {/* 要注释的内容*/}
- v-if 条件渲染 1.三元表达式 2.|| 3.函数内部控制返回值
- v-for 列表渲染 react 中数组的每一项会被展开
- v-bind 属性绑定 属性名={ 表达式} 类名不能用class 用className
- v-on 事件绑定 和原生js类似 onclik onClick
兄弟 状态提升 上下文 全局状态管理
列表循环
<script src="../base/react.min.js"></script>
<!-- 提供react 对象 -->
<script src="../base/react-dom.min.js"></script>
<!-- 提供react dom 对象 -->
<script src='../base/browser.min.js'></script>
<!-- 帮助浏览器解析jsx语法 -->
</head>
<body>
<div id='app'>
</div>
<script type='text/babel'>
let Component = React.createClass({
getInitialState(){
return{
arr:['爱情','恐怖','动作'] //=>[<li>1</li>,<li>2</li>]
}
},
render(){
return(
<ul>
{this.state.arr.map((item,index)=>{
return (<li>{item}</li>)
})}
</ul>
)
}
})
ReactDOM.render(<Component/>,app)
/*
在react 中没有v-for
渲染数组会将数组的每一项进行拆分 结合map方法实现列表渲染
*/
</script>
</body>
条件渲染
方法一:三元表达式 {this.state.show?'呵呵':'嘻嘻'}
方法二:或 运算与 ||
方法三:函数处理
属性绑定
- react 中属性绑定:类名要用className
let Component = React.createClass({
getInitialState(){
return{
color:false
}
},
render(){
return(
<div className={this.state.color?"red":"blue"}>
</div>
)
}
})
ReactDOM.render(<Component/>,app)
事件绑定
- react 不像vue 数据变化页面自动改变
- react 中数据改变了 想让页面更新 需要通过 setState方法
如果没有参数 默认参数就是事件对象
事件的处理函数不要加() 加了() 相当于自执行
如果要传参数 通过 bind 进行传参 fun.bind(this,params1,params2 …) 默认参数会放到参数的最后方
或者 在事件处理函数 函数的内部执行要触发的函数 默认是没有事件对象 要从外部函数进行获取
Tab选项卡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="../base/react.min.js"></script>
<!-- 提供react 对象 -->
<script src="../base/react-dom.min.js"></script>
<!-- 提供react dom 对象 -->
<script src='../base/browser.min.js'></script>
<!-- 帮助浏览器解析jsx语法 -->
<style>
*{
margin:0;
padding:0;
}
ul{
margin:0 auto;
height:100px;
width:600px;
display:flex;
}
ul li{
list-style: none;
width:200px;
height:100px;
/* background:pink; */
display:flex;
justify-content: center;
align-items: center;
}
ol{
margin:0 auto;
height:400px;
width:600px;
overflow: hidden;
}
ol li{
width:600px;
height:200px;
background:powderblue;
display:flex;
justify-content: center;
align-items: center;
}
.blue{
background: paleturquoise;
}
.pink{
background: palegreen;
}
</style>
</head>
<body>
<div id='app'>
</div>
<script type='text/babel'>
let Component = React.createClass({
getInitialState(){
return{
tabs:['地狱使者','sunny','鬼怪大叔'],
selIndex:0
}
},
changeIndex(index){
//修改默认选中项
this.setState({selIndex:index})
console.log(this);
},
renderContent(){
// 将内容元素进行封装
let content=this.state.tabs[this.state.selIndex]
return (
<div>
{content}
</div>
)
},
render(){
let {tabs,selIndex}= this.state
return(
<div>
<ul>
{
tabs.map((item,index)=>{
return (<li className={selIndex===index?'pink':'blue'}
onClick={this.changeIndex.bind(this,index)}
>{item}</li>)
})
}
</ul>
<ol>
<li>{this.renderContent()}</li>
</ol>
</div>
)
}
})
ReactDOM.render(<Component/>,app)
/*
1. tab显示
2. 点击tab切换样式
3. 点击控制div的显示隐藏
*/
</script>
</body>
</html>
ref
<div id='app'>
</div>
<script type='text/babel'>
let Component = React.createClass({
getDom(){
console.log(this.refs)
},
render(){
console.log(this.refs.hehe)
return(
<div>
<span ref='hehe'>djdjd</span>
<p ref='hehe'>hehehe</p>
<button onClick={()=>{
this.getDom()
}}>getDom</button>
</div>
)
}
})
ReactDOM.render(<Component/>,app)
/*
ref用法1 和vue中一样可以绑定一个元素
绑定后通过 this.refs 进行获取
*/
</script>
<body>
<div id='app'>
</div>
<script type='text/babel'>
let Father = React.createClass({
render(){
return(
<div>
<h1>这里是父组件</h1>
<hr/>
<Son>
你好
</Son>
</div>
)
}
})
let Son = React.createClass({
render(){
console.log(this)
return(
<div>
<h3>这里是子组件</h3>
{this.props.children}
</div>
)
}
})
ReactDOM.render(<Father/>,app)
/*
组件标签内部的内容默认也是不渲染的
但是我们可以组件对象里 的props.children 进行获取
*/
</script>
</body>
<body>
<div id='app'>
</div>
<script type='text/babel'>
let Father = React.createClass({
render(){
return(
<div>
<h1>这里是父组件</h1>
<hr/>
<Son ref='hehe'></Son>
<button onClick={()=>{
console.log(this)
}}>get</button>
</div>
)
}
})
let Son = React.createClass({
getInitialState(){
return{name:123}
},
test(){
},
render(){
return(
<div>
<h3>这里是子组件</h3>
</div>
)
}
})
ReactDOM.render(<Father/>,app)
/*
ref 除了给dom元素使用 还可以给组件使用
可以获取到绑定的组件对象 (获取子组件里的方法和数据)
*/
</script>
</body>
组件通信
- 父子
- props 传参 将父组件的数据传给子组件
- ref 绑定一个组件 父组件调用子组件的方法
- 子父 props 传递父组件的方法
数据承载 - props
<div id='app'>
</div>
<script type='text/babel'>
let Father = React.createClass({
getInitialState(){
return{
name:'殷乡梅'
}
},
render(){
return(
<div>
<h1>这里是父组件</h1>
<Son hehe={this.state.name}></Son>
</div>
)
}
})
let Son = React.createClass({
getDefaultProps(){ //getDefaultProps 初始化props的默认值
return{
hehe:'韩梅梅'
}
},
render(){
console.log('son',this)
return(
<div>
<h3>这里是子组件</h3>
{this.props.hehe}
{/*props默认值和外部传递冲突 以外部为准*/}
</div>
)
}
})
ReactDOM.render(<Father/>,app)
</script>
</body>
setState异步
<div id='app'>
</div>
<script type='text/babel'>
let Father = React.createClass({
getInitialState(){
return{
num:1
}
},
add(){
// let num=++this.state.num
setTimeout(()=>{
// setState 方法是一个异步的,在同步中多次执行setState 会被 合并 只触发一次render,
//如果在异步中执行setState 不会被合并 setState相当于同步,有几次setState执行几次render
this.setState({num:1})
this.setState({num:2})
this.setState({num:3})
this.setState({num:4})
},1000)
},
render(){
console.log('渲染了')
return(
<div>
<h1>父组件</h1>
{this.state.num}
<button onClick={this.add}>增加</button>
</div>
)
}
})
ReactDOM.render(<Father/>,app)
</script>
</body>