1、react初始案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入核心库,先核心库,在rect-dom操作dom库,最后babel注意顺序-->
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
</head>
<body>
<div id="test"></div>
<!-- 下面不能默认写默认js,必须写type并且是bable,实际是jax -->
<script type="text/babel">
//1、创建虚拟dom
const VDOM=<h1>hello react</h1> /*此处不用写引号,因为不是字符串,jax特有的*/
//2、渲染虚拟dom到页面,render三个参数,1,虚拟dom,2,渲染到的容器,3、回调函数
ReactDOM.render(VDOM,document.getElementById('test'))
</script>
</body>
</html>
2、React.createElement()创建虚拟dom避免写jax语法(不建议,还是建议jax)
React.createElement()三个参数
1、标签名
2、标签属性,用json形式
3、标签内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入核心库,先核心库,在rect-dom操作dom库,最后babel注意顺序-->
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
</head>
<body>
<div id="test">
<div id="title"></div>
</div>
<!-- 下面不能默认写默认js,必须写type并且是bable,实际是jax -->
<script type="text/javascript">
//1、创建虚拟dom
const VDOM=React.createElement('div',{id:'title'},'hello my React')
//2、渲染虚拟dom到页面,render三个参数,1,虚拟dom,2,渲染到的容器,3、回调函数
ReactDOM.render(VDOM,document.getElementById('test'))
</script>
</body>
</html>
最终还是建议jax,可以避免嵌套过多的情况,jax实质上就是语法糖,使用小括号后,虚拟dom的dom表达部分可以换行,缩进等
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入核心库,先核心库,在rect-dom操作dom库,最后babel注意顺序-->
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
</head>
<body>
<div id="test">
<div id="title"></div>
</div>
<!-- 下面不能默认写默认js,必须写type并且是bable,实际是jax -->
<script type="text/babel">
//1、创建虚拟dom
const VDOM=(<h1>
<span>
</span>
</h1>)
//2、渲染虚拟dom到页面,render三个参数,1,虚拟dom,2,渲染到的容器,3、回调函数
ReactDOM.render(VDOM,document.getElementById('test'))
</script>
</body>
</html>
3、jax语法规则1(模板语法)
- 1、定义虚拟dom时,不要写引号
- 2、标签中混入js表达式需要使用{}
- 3、变量最好使用小写,或者使用tolowcase
- 4、使用样式需要使用className属性,而不是class
- 5、内联style样式,需要使用style={{key:value}}
- 6、react只允许有一个根元素(类似于vue)
- 7、标签必须闭合
- 8、标签首字母,
a、如果小写,则将该标签转为html同名元素,若无对应同名标签,则报错,
b、如果大写开头,则去渲染对应的组件,如果没有该组件,则报错
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入核心库,先核心库,在rect-dom操作dom库,最后babel注意顺序-->
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
<style type="text/css">
.mystyle{ background-color: orange}
</style>
</head>
<body>
<div id="test">
<div id="title"></div>
</div>
<!-- 下面不能默认写默认js,必须写type并且是bable,实际是jax -->
<script type="text/babel">
//1、创建虚拟dom
const myid='nEwId'
const mydata='hello jax'
const VDOM=(
<div>
<div className="mystyle" id={myid.toLowerCase()} style={{fontweight: 'bold',color:'green'}}>{mydata}</div>
</div>
)
//2、渲染虚拟dom到页面,render三个参数,1,虚拟dom,2,渲染到的容器,3、回调函数
ReactDOM.render(VDOM,document.getElementById('test'))
</script>
</body>
</html>
4、jax语法规则2
{}内只能写表达式,不能写语句。
表达式是一个可以放在任意地点的代码,他会返回一个值
语句是一系列逻辑
遍历可遍历对象是,应当使用key做序列,提高虚拟dom效率
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入核心库,先核心库,在rect-dom操作dom库,最后babel注意顺序-->
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
</head>
<body>
<div id="test">
</div>
<!-- 下面不能默认写默认js,必须写type并且是bable,实际是jax -->
<script type="text/babel">
const datas=['angular','react','vue']
//1、创建虚拟dom
const vdom=(
<div>
<h1>
<ul>
{datas.map((item,index)=>{
return <li key={index}>{item}</li>
})}
</ul>
</h1>
</div>
)
//2、渲染虚拟dom到页面,render三个参数,1,虚拟dom,2,渲染到的容器,3、回调函数
ReactDOM.render(vdom,document.getElementById('test'))
</script>
</body>
</html>
5、react面向组件编程
安装react developer Tools
参考:
安装方法
下载地址
https://www.crx4chrome.com/crx/3068/
6、函数式组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入核心库,先核心库,在rect-dom操作dom库,最后babel注意顺序-->
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
</head>
<body>
<div id="test">
</div>
<!-- 下面不能默认写默认js,必须写type并且是bable,实际是jax -->
<script type="text/babel">
//1、创建函数式组件
function MyComnponent(){
return (
<div>
<h2>这是我的一个标签</h2>
<ul>
<li>这是一个列表</li>
</ul>
</div>
)
}
//2、渲染虚拟dom到页面,render三个参数,1,虚拟dom,2,渲染到的容器,3、回调函数
ReactDOM.render(<MyComnponent/>,document.getElementById('test'))
</script>
</body>
</html>
7、类式组件
类式组件创建组件的时候必须继承React.Component
执行了ReactDom.render()之后发生了什么
- 1、类式组件使用类定义,随后new出来该类的实例(渲染组件的时候自动创建),并通过该实例调用到原型上的render方法
- 2、将render返回的虚拟dom转为正式dom,随后呈现在页面中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入核心库,先核心库,在rect-dom操作dom库,最后babel注意顺序-->
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
</head>
<body>
<div id="test">
</div>
<!-- 下面不能默认写默认js,必须写type并且是bable,实际是jax -->
<script type="text/babel">
//1、创建类式组件,必须继承react内置的Component类
class MyComponent extends React.Component{
render(){
return <h1>hello , i am a component</h1>
}
}
//2、渲染虚拟dom到页面,render三个参数,1,虚拟dom,2,渲染到的容器,3、回调函数
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
</script>
</body>
</html>
8、react三大属性state
state是在组件实例上的,默认为null,其实应该是个空对象
state是用来存放一些数据的,通过自定义对象的形式给state添加至
state由于是在实例上的,因此,可以通过this.state来获得state上的数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入核心库,先核心库,在rect-dom操作dom库,最后babel注意顺序-->
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
</head>
<body>
<div id="test">
</div>
<!-- 下面不能默认写默认js,必须写type并且是bable,实际是jax -->
<script type="text/babel">
//1、创建类式组件,必须继承react内置的Component类
class MyComponent extends React.Component{
constructor (props) {
super(props)
this.state={ishot:false}//state需要是对象
}
render(){
const {ishot}=this.state
console.log(this)
return <h1>今天天气很{ishot?'炎热':'凉爽'}</h1>
}
}
//2、渲染虚拟dom到页面,render三个参数,1,虚拟dom,2,渲染到的容器,3、回调函数
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
</script>
</body>
</html>
9、react中绑定事件
react重写了所有时间因此原生js中的onclick变成了onClick
建议在渲染标签的内容中写事件,事件对应的回调函数直接写函数名,不要写小括号(那是调用)
<!-- 下面不能默认写默认js,必须写type并且是bable,实际是jax -->
<script type="text/babel">
//1、创建类式组件,必须继承react内置的Component类
class MyComponent extends React.Component{
constructor (props) {
super(props)
this.state={ishot:false,wind:'微风'}//state需要是对象
}
render(){
const {ishot}=this.state
console.log(this)
return <h1 onClick={clikDemo}>今天天气很{ishot?'炎热':'凉爽'}</h1>
}
}
//2、渲染虚拟dom到页面,render三个参数,1,虚拟dom,2,渲染到的容器,3、回调函数
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
//3、创建事件的回调函数
function clikDemo () {
console.log('title被点击了')
}
</script>
10、解决this指向问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入核心库,先核心库,在rect-dom操作dom库,最后babel注意顺序-->
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
</head>
<body>
<div id="test">
</div>
<!-- 下面不能默认写默认js,必须写type并且是bable,实际是jax -->
<script type="text/babel">
//1、创建类式组件,必须继承react内置的Component类
class MyComponent extends React.Component{
constructor (props) {
super(props)
this.state={ishot:false,wind:'微风'}//state需要是对象
this.changeWeather=this.changeWeather.bind(this)//这个非常关键,不用去that=this了,解决了this的指向问题
}
render(){
const {ishot}=this.state
console.log(this)
return <h1 onClick={this.changeWeather}>今天天气很{ishot?'炎热':'凉爽'}</h1>
}
//3、创建事件的回调函数
changeWeather () {
console.log(this.state.ishot)
}
}
//2、渲染虚拟dom到页面,render三个参数,1,虚拟dom,2,渲染到的容器,3、回调函数
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
</script>
</body>
</html>
11、state状态的更改
state状态不能直接更改,要使用内置api更改
使用setState方法来修改
另外:
- //创建事件的回调函数,这里将changeWeather作为赋值使用,使得changeweather变成了一个类的实例方法,
- //使用箭头函数的好处就是箭头函数自身没有this,他会去寻找自己外层的this
- //自定义方法要使用赋值语句+箭头函数的形式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入核心库,先核心库,在rect-dom操作dom库,最后babel注意顺序-->
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
</head>
<body>
<div id="test">
</div>
<!-- 下面不能默认写默认js,必须写type并且是bable,实际是jax -->
<script type="text/babel">
//1、创建类式组件,必须继承react内置的Component类
class MyComponent extends React.Component{
//初始化状态,这里不用使用this,因为直接在类里使用
state={ishot:false,wind:'微风'}//state需要是对象
render(){
const {ishot,wind}=this.state
return <h1 onClick={this.changeWeather}>今天天气很{ishot?'炎热':'凉爽'},{wind}</h1>
}
//创建事件的回调函数,这里将changeWeather作为赋值使用,使得changeweather变成了一个类的实例方法,
//使用箭头函数的好处就是箭头函数自身没有this,他会去寻找自己外层的this
//自定义方法要使用赋值语句+箭头函数的形式
changeWeather= ()=> {
const ishot=this.state.ishot
//特别注意,状态必须通过setState进行更新,且更新是一种合并,不是替换
this.setState({ishot:!ishot})
}
}
//2、渲染虚拟dom到页面,render三个参数,1,虚拟dom,2,渲染到的容器,3、回调函数
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
</script>
</body>
</html>
12、state的一些理解
- state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)
- 组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)
- 组件中render方法中的this为组件实例对象
- 组件自定义的方法中this为undefined,如何解决?
a) 强制绑定this: 通过函数对象的bind()
b) 箭头函数 - 状态数据,不能直接修改或更新