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