一、了解React
- ⽤于构建⽤户界⾯的 JavaScript 库
- 学习React需要⽐较牢固的JS基础和熟悉ES6语法
- React没有太多的api,可以说⽤react编程都是在写 JS
二、项目目录架构
三、了解 react 和 react-dom 两个库
- react只做逻辑层
- react-dom做渲染层,去渲染实际的DOM
import React from 'react'
import ReactDom from 'react-dom'
四、JSX的实质
JSX语法即JS和html的混合体,实际的核⼼逻辑就是⽤js去实现的。JSX的实质就是React.createElement 的调⽤。
五、state
在组件⾥⾯我们通过 { } 在JSX⾥⾯渲染变量。
如果数据需要修改,并且需要⻚⾯同时响应改变,那就需要把变量放在 state ⾥⾯,同时使⽤setState 修改
- 初始状态state
// 初始状态
this.state = {count:0
}
- 更新状态使⽤ setState ,不能使用 this.state.count = ???
//更新状态
this.setState({count:this.state.count+1
})
注意事项:
- setState是异步的,底层设计同⼀个⽣命周期会批量操作更新
- state setState第⼆个参数是⼀个可选参数,传⼊⼀个回调函数可以 获取到最新的state
this.setState({count:this.state.count+1
},()=>{console.log(this.state.count,'后输出的') // 1
})
console.log(this.state.count,'先输出的') // 0
- 当修改的state依赖上⼀次修改的state的值时,可使⽤以下这种⽅法修改
this.setState((prevState,prevProps)=>{return{count:prevState.count+1}
})
以上两段代码可以简写为
this.setState((prevState,prevProps)=>({count:prevState.count+1
}
),()=>{console.log(this.state.count,'后输出的')
})
console.log(this.state.count,'先输出的')
六、props属性传递
⽗组件向⼦组件传递属性利⽤props接收
//⽗组件<App>传⼊
<PropsDemo title="Tim⽼师教react"></PropsDemo>
子组件使用(3种)
- class组件使用(不常用)
import React, { Component } from 'react'export default class PropsDemo extends Component {render() {return (<div>this.props.title</div>)}
}
- 函数型组件使用
import React from 'react'export default function PropsDemo() {return (<div>{props.title}</div>)
}
- 解构赋值写法
export default function PropsDemo({title}) {return (<div>{title}</div>)
}
七、条件渲染
条件渲染写法有3种,⼀般使⽤三⽬表达式
- 三目表达式
{this.state.showTitle?<h2>{this.props.title}</h2>:null}
- render函数⾥定义⼀个变量装载结果
let result=this.state.showTitle?<h2>{this.props.title}</h2>:nullreturn (<div>{result}</div>
)
- if else 写法
let result
if(this.state.showTitle){result=(<h2>{this.props.title}</h2>)
}else{result=null
}
八、数据循环渲染
构造函数中有一个goods数组,存放 title 和 price 数据
constructor(props){super(props)this.state={showTitle:true,goods: [{ title: 'html+css基础⼊⻔', price: 19.8},{ title: 'js零基础阶级', price: 29.8},{ title: 'vue基础⼊⻔', price: 19.8},{ title: 'vue电商单⻚⾯项⽬实战', price:39.8},{ title: 'react零基础进阶单⻚⾯项⽬实战',price: 59.8},]}
}
render中数据循环渲染
<ul>{this.state.goods.map(good=>{ // good是随便起的变量名return <li key={good.title}><span>课程名称:{good.title}</span>----<span>价格:{good.price}</span></li>})}
</ul>
九、事件监听
以点击事件为例⼦,使⽤⽅法如下(⼩驼峰写法,事件名⽤ {} 包裹):
<button onClick={}></button>
由于 react 的 this 指向问题,所以在事件绑定时要特别注意,否则会出现 bug。
- 第一种事件绑定:bind绑定
// 事件绑定第一种和第二种使用的dom写法
<button onClick={this.showTitleFun} > 不显示title </button>
// 第一种和第三种事件绑定写法 调用的方法
showTitleFun(){this.setState({showTitle:false})
}
constructor(props){super(props)this.state={showTitle:true,// 事件绑定第一种写法 改变this指向this.showTitleFun=this.showTitleFun.bind(this)
}
- 第二种事件绑定:箭头函数
// 第二种事件绑定写法 利用箭头函数改变this指向
showTitleFun = () => {this.setState({showTitle:false})
}
- 第三种事件绑定:直接使⽤箭头函数返回⼀个函数
// 事件绑定第三种使用的dom写法
<button onClick={()=>this.showTitleFun()} > 不显示title </button>
十、React样式编写
- 行内样式
<img style={{width:'240px',height:'60px'}} />
- 添加类名
<img className="img" />
- 添加属性
<img src={logo} />
合并写法:
<img src={logo} style={{width:'240px',height:'60px'}} className='xdlogo' />
十一、React实现双向数据绑定
React 实现 input 的双向数据绑定要点
- 动态绑定value属性
//在state⾥⾯定义⼀个变量绑定input的value属性
this.state={inputval:'我是input的初始值'
}//然后在input⾥动态绑定上⾯定义的变量
<input type="text" value={this.state.inputval} />
- 监听input的onChange事件
// 定义 绑定input的onChange事件
inputvalChange=(e)=>{console.log(e.target.value)this.setState({inputval:e.target.value})
}
//在input上绑定绑定inputvalChange到onChange上
<input type="text" value={this.state.inputval} onChange={e=>this.inputvalChange(e)} />
十二、React组件⽣命周期
// 子组件
class LifeCycleSon extends Component {constructor(props){super(props)console.log('1.构造函数')}componentWillMount(){// 组件将要挂载,这个时候可以进行api的调用,获取数据,但是不能进行dom操作console.log('2.组件将要挂载')}componentDidMount(){// 此时组件已经挂载,这个时候可以进行dom操作,可以对状态进行更新操作console.log('4.组件已经挂载')}componentWillReceiveProps(){// 父组件传递的属性有变化,可以在这里做相应的响应操作console.log('5.父组件属性更新')}shouldComponentUpdate(){// 组件是否需要更新,需要返回一个布尔值,返回true更新,返回false不更新console.log('6.组件是否应该更新,需要返回布尔值')return true}componentWillUpdate(){// 组件将要更新console.log('7.组件将要更新')}componentDidUpdate(){// 组件已经更新console.log('8.组件已经更新')}componentWillUnmount(){// 组件销毁console.log('9.组件已经销毁')}render() {console.log('3.组件渲染')return (<div>组件生命周期</div>)}
}// 父组件
export default class LifeCycle extends Component {constructor(props){super(props)this.state={son:'生命周期',showSon:true}setTimeout(() => {this.setState({son:'更新'})}, 2000);setTimeout(() => {this.setState({showSon:false})}, 4000);}render() {return (<div>{this.state.showSon?<LifeCycleSon title={this.state.son}></LifeCycleSon>:<div>组件已销毁</div>}</div>)}
}