基础配置导入所需的react文件
<!-- react框架文件 -->
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<!-- react用来渲染页面的文件 -->
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 用来编译jsx语法的库 -->
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
- html模板
- ReactDOM.render()
- JSX 语法
- 组件 & props
- props & 纯函数
- 绑定事件
- bind
- 列表渲染
- 条件渲染
- this.state
- style和class
- 生命周期
- 表单
- 获取真实的DOM节点
- this.props.children
1&2 在DOM节点(app)中渲染所需的标签(html)
ReactDOM.render(a,b)
参数1: a代表HTML的东西
参数2: b代表渲染的节点
<body>
<!-- 渲染的div -->
<div id="app">
</div>
<script type="text/babel">
ReactDOM.render(
//第一个参数(html)
<h3>hellow,world</h3>,
// 第二个参数,节点
document.querySelector('#app')
)
</script>
</body>
3. JSX 语法
JSX 就是用来声明 React 当中的元素。(html)
JSX 是在 JavaScript 内部实现的。
{}里执行js代码<>执行html代码
<body>
<div id="app">
</div>
<script type="text/babel">
//声明一个对象
const person={
name:'hxt',
age:21
}
//声明一个常量 为html(jsx)
const element=
<div>
<h3>名字:{person.name}</h3>
<h3>年龄:{person.age}</h3>
</div>
//将值放入所需的参数位置
ReactDOM.render(
element,
document.getElementById('app')
)
</script>
</body>
4. 组件 & props
这里需要用到es6的继承类(所继承的类将会有继承的类的东西)
使用class
声明一个类(类为大写开头,所继承的类开头也为大写)
类里不是个对象,后面不需要写逗号
1.构造器,初始化实例(可接受参数)
-
super()
(固定)将父类中的this对象继承给子类 - new类后将会执行一次
constructor
2.class Xxx extends Aaa
类Xxx继承Aaa
示例代码
<script>
//定义一个类
class Person{
constructor(){
this.mouth = '1张';
this.leg='两条';
}
eat(){
console.log('你真能吃')
}
speak(){
console.log('你真能说')
}
}
var person = new Person();
console.log(person)
//继承
class Man extends Person {
constructor(name,age) {
// 执行父类构造器
super();
this.name = name;
this.age = age;
}
}
var man = new Man('张三',100);
console.log(man);
console.log(man.leg);
man.speak();
</script>
react示例代码
1.声明一个子类,需要继承 (注意大写)
-
需要返回子组件所放置html的地方(相当于vue的
template
)
3.将声明继承的类组件 放入ReactDOM.render()
参数1里
<body>
<div id="app">
</div>
<script type="text/babel">
//定义一个子组件继承react的组件
class Person extends React.Component{
//构造器,初始化实例
constructor(props){
//接受参数(固定)将父类中的this对象继承给子类
super(props)
}
//渲染的子组件(相当于vue的template)
render(){
//需用return返回
return(
//使用{}来使用JS代码
<h3>
<div>名字:{this.props.name}</div>
<div>年龄:{this.props.age}</div>
</h3>
)
}
}
ReactDOM.render(
//整个div为父组件,Person标签为子组件,Person 里传参数
<div>
<div>你好呀</div>
<hr/>
<Person name="hxt" age="21"/>
</div>,
document.getElementById('app')
)
</script>
</body>
5.props & 纯函数
纯函数即为不受外界影响,值可以确定的函数
纯函数
sum(a,b){
return a+b
}
sum(1,2)
sum(1,2)
sum(1,2)
sum(1,2)
不纯的函数(不确定的值)
let abc=1
sum(a,b){
abc++
return a*b+abc
}
sum(1,2)
sum(1,2)
sum(1,2)
6.绑定事件
bind(绑定所指向的this)
<script>
var person = {
language: '粤语',
speak() {
console.log(this);
console.log(`他会讲${this.language}`);
}
}
person.speak();
// 使用bind绑定函数执行时的this
var speak = person.speak.bind(person);
speak();
</script>
onClick(C为大写)
<body>
<div id="app">
</div>
<script type="text/babel">
class Demo extends React.Component {
constructor(props) {
super(props)
//绑定this指向
this.num = this.num.bind(this)
}
render() {
return (
<div>
<ul>
<li><button onClick={() => { this.num(1001) }}>点击1</button></li>
<li><button onClick={() => { this.num(1002) }}>点击2</button></li>
<li><button onClick={() => { this.num(1003) }}>点击3</button></li>
</ul>
</div>
)
}
num(data) {
alert(data)
}
}
ReactDOM.render(
<Demo />,
document.querySelector('#app')
)
</script>
</body>
7. 列表渲染
1.利用数组的map来渲染页面
2.es6解构
3.传入参数list
<div id="app">
</div>
<script type="text/babel">
//定义一个子组件继承react的组件
class Person extends React.Component{
//构造器,初始化实例
constructor(props){
//接受参数(固定)将父类中的this对象继承给子类
super(props)
}
//渲染的子组件(相当于vue的template)
render(){
// let list = this.props.list;
let {list} = this.props
//需用return返回
return(
//使用{}来使用JS代码
<ul>
{
//使用map来渲染列表
list.map((item,index)=>{
return(
<li key={index}>{item.name}</li>
)
})
}
</ul>
)
}
}
const list=[
{
name:'hxt',
age:21
},
{
name:'cc',
age:22
},
{
name:'hh',
age:18
},
{
name:'aa',
age:11
}
];
ReactDOM.render(
<Person list={list}/>,
document.getElementById('app')
)
</script>
用state数据来渲染
1.生命周期(componentDidMount...)
2.设置state
3.axios
4.更改state
5.数组map渲染
class HotFilm extends React.Component{
constructor(props){
super(props)
this.state={
filmList:[]
}
}
componentDidMount() {
const url="http://huruqing.cn:3000/api/film/getList"
axios.get(url).then(res=>{
console.log(res)
this.setState({
filmList:res.data.films
})
}).catch(err=>{
console.log(err)
})
}
render(){
let {filmList} =this.state
return(
<ul className="list">
{
filmList.map(item=>{
return (
<li className="item flex jc-sb pt-15" key={item.filmId}>
<div className="film flex jc-sa ml-10">
<img src={item.poster} className="image "/>
<div className="ml-10 lh15">
<p className="f16">{item.name} <span className="type">{JSON.parse(item.filmType).name}</span></p>
<p className="f14 gray">观众评分 <span className="yellow">{item.grade}</span> </p>
<p className="f14 gray actor">主演:{item.actorStr}</p>
<p className="f14 gray">{item.nation} | {item.runtime}分钟</p>
</div>
</div>
<div className="buttbox">
<button className="butt mr-10">购票</button>
</div>
</li>
)
})
}
</ul>
)
}
}
8. 条件渲染
1.利用三目运算来选择是否显示html
例:是否显示样式
<div className={pageName==='index'?"flex2 fcc active":"flex2 fcc gray"}>
<i className=" f20 iconfont icon-shouye"></i>
<p className="f12">首页</p>
</div>
9. this.state
利用this.state来存放数据(相当于vue的data)
constructor() {
super()
this.state = {
list: []
}
}
修改state值需用 this.setState({})
例如
this.setState = {
list: [1,2,3]
}
10. style和class
1.style
<div style={{border:'1px solid red'}}></div>
2.class
react的class是用className来替代的
index-default-page是个类
<div className="index-default-page"></div>
11. 生命周期
1、getDefaultProps()
设置默认的props,也可以用dufaultProps设置组件的默认属性.
2、getInitialState()
在使用es6的class语法时是没有这个钩子函数的,可以直接在constructor中定义this.state。此时可以访问this.props
3、componentWillMount()
组件初始化时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state。
4、 render()
react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。
5、componentDidMount()
组件渲染之后调用,只调用一次。
更新
6、componentWillReceiveProps(nextProps)
组件初始化时不调用,组件接受新的props时调用。
7、shouldComponentUpdate(nextProps, nextState)
react性能优化非常重要的一环。组件接受新的state或者props时调用,我们可以设置在此对比前后两个props和state是否相同,如果相同则返回false阻止更新,因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能,尤其是在dom结构复杂的时候
8、componentWillUpdata(nextProps, nextState)
组件初始化时不调用,只有在组件将要更新时才调用,此时可以修改state
9、render()
组件渲染
10、componentDidUpdate()
组件初始化时不调用,组件更新完成后调用,此时可以获取dom节点。
卸载
11、componentWillUnmount()
组件将要卸载时调用,一些事件监听和定时器需要在此时清除。
12. 表单(当函数不传值就进行接收时接收的为此时的状态)(ev.target为当前函数标签的内容)
class Person extends React.Component{
//构造器,初始化实例
constructor(props){
//接受参数(固定)将父类中的this对象继承给子类
super(props)
this.login=this.login.bind(this)
this.state={
username:'hxt',
passwd:'123'
}
}
//渲染的子组件(相当于vue的template)
render(){
let {username,passwd} = this.state
//需用return返回
return(
<div>
<input name="username" value={username} onChange={this.login}/>
<input name="passwd" value={passwd} onChange={this.login}/>
</div>
)
}
login(ev){
console.log(ev);
console.log(ev.target);
let target = ev.target;
let name = target.name;
this.setState({
[name]: ev.target.value
})
}
}
ReactDOM.render(
<Person />,
document.getElementById('app')
)
13. 获取真实的DOM节点
ref属性
ref可以挂载到组件上也可以是dom元素上;
挂到组件(class声明的组件)上的ref表示对组件实例的引用。不能在函数式组件上使用 ref 属性,因为它们没有实例:
挂载到dom元素上时表示具体的dom元素节点。