0%

react 开课吧学习笔记

30 React JSX 组件化 React开发模式 生命周期

  • 默认端口3000

  • react代码保存后自动格式化,一堆错误

    点击右下角的javaScript, 在弹出的选择框中, 输入选择JavascriptReact或者TypescriptReact

jsx的本质

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
jsx的写法  : babel左了转换
class HelloMessage extends React.Component {
render() {
return (
<div id='name' class='red'>
Hello {this.props.name} {this.props.age}
</div>
);
}
}

ReactDOM.render(
<HelloMessage name="Taylor" />,
document.getElementById('hello-example')
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
非jsx的写法
class HelloMessage extends React.Component {
render() {
return React.createElement(
'div', // 标签
{ id: 'name', 'class': 'red' }, // 属性
'Hello ', // 内容
this.props.name,
' ',
this.props.age
);
}
}

ReactDOM.render(React.createElement(HelloMessage, { name: 'Taylor' }), document.getElementById('hello-example'));
  • 前端框架使用成员好像一律都用this, 不存在之前c#那样可以直接成员变量的
  • 在构造函数中初始化数据成员白能量,类外部没有数据成员变量,可以有函数成员变量,,es6 class应该就是这样, ts中好像可以先声明成员变量,构造函数中初始化 todo

react双向数据绑定及事件this的写法

  • react是单向数据流,需要实现onChange事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
render() {  // {}类似vue的{{}}
return <div>
<input type="text" value={this.state.text} onChange={
(e)=>{
// console.log(e)
// this.setState({
// text:e.target.value // 手动双向数据绑定 ,,MV是默认的,需要实现VM
// })
this.vmHandler(e) // 内层的话 必须传递e,, 自定义参数时也可以使用嵌套函数的方式传递参数,外层的参数是事件调用时默认会传递event
}

//this.vmHandler2 // 方式二


}/>

</div>
}



vmHandler(e){
// console.log(e);
// console.log(this)
this.setState({
text:e.target.value // 手动双向数据绑定 ,,MV是默认的,需要实现VM
})
}


vmHandler2=(e)=>{ // 如果写e,会获取到event 方式二
console.log(e);
// console.log(this)
this.setState({
text:e.target.value // 手动双向数据绑定 ,,MV是默认的,需要实现VM
})
}
  • react里this用的很多,模板和脚本在一起,模板里的变量也得带this,, 事件的话最好用()=>{this.method},箭头函数的this就是组件,传递event的话,加上(e)=>{}即可。

    • 其他调用方式: 方法简单的话,可以直接在render里写方法体

      方式二: 事件{}中 直接写方法名,此时该方法是别人调用的,this不代表当前组件了, 但方法中使用this时,方法也要用箭头函数保留this指向

      分析:如果是放在了箭头函数中 调用this.method(),则method中的this肯定就是定义时的上下文this,代表当前组件, 否则的话需要注意method函数体中的this指向; 事件绑定机制的处理造成了event的传递,this的问题; 暂时就用箭头函数把 需要使用定义时的this 上下文保留; 之前vue模板中绑定的数据变量/事件中的变量都不用写this,,应该是框架处理机制的不同,vue只是解析得到方法名或变量名,不需要this, react render里是要后面直接按变量用的

      方式三: 在构造函数中绑定函数的this指向,因为肯定先经过构造函数,通过bind绑定的函数的this指向不再变

      this.vmHandler = this.vmHandler .bind(this),, 此种方式也可以在onChange中直接用bind(this),不过那样每次render都要bind,性能不好

    • 注意react事件里,不要写函数执行的方式,,那样会执行再赋值,事件是无效的,这和html中好像不一样

  • react标签没有子元素,可以用单标签

  • 单向数据流的优点:: 防止bug,, js中有些数据是会互相影响的(引用类型?),,每次修改数据都setState, 都使用新的数据,不会有这种问题

函数组件

  • 适用于局部 返回一个简单的小片段组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 函数组件: 如果一个组件只是根据props进行渲染,没有内部的state,可以用函数形式代替(hook 函数发展方向)

app.js
export function Title({title}){ // 参数解构赋值
return <div>
<h2>{title}</h2>
<hr/>
</div>
}


index.js
ReactDom.render( // render 中组件的标签名起始大写
<Title title='我是函数组件'></Title>, // 函数组件,仅依赖props,不需要state时可以使用
document.querySelector('#root')
)


-------------------------------
cart.js 总价
// 函数组件: 返回商品总价, react没有计算属性,直接把计算逻辑写在模板里,,类似的小片段可用函数组件实现,,参数接收的是props
function Total({cart}){
return <span>总价:{cart.reduce((sum,a)=>{
return sum+=a.price * a.count;
}, 0)}</span>
}

<tfoot>
<Total cart={this.props.data}></Total>
</tfoot>

31 React JSX 组件化 React开发模式 生命周期

按需加载插件

组件拆分 ,嵌套

  • 组件可以按行为和展示进行拆分,, 组件render时render另外一个组件,组件按组件类名作为标签进行使用; 解耦/复用/易于测试
  • 体会一下本质,, 递归实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
jsx语法
class HelloMessage extends React.Component {
render() {
return (
<Hello name="ccb"></Hello>
);
}
}
class Hello extends React.Component {
render() {
return (
<div>
Hello {this.props.name}
</div>
);
}
}

ReactDOM.render(
<HelloMessage name="Taylor" />,
document.getElementById('hello-example')
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
非jsx语法

class HelloMessage extends React.Component {
render() {
return React.createElement(Hello, { name: "ccb" }); //发现Hello是组件标签,则会按Hello的render去React.createElement,,递归
}
}
class Hello extends React.Component {
render() {
return React.createElement(
"div",
null,
"Hello ",
this.props.name
);
}
}

ReactDOM.render(React.createElement(HelloMessage, { name: "Taylor" }), document.getElementById('hello-example'));

react三点运算符

  • <Component {…props}/>
    • react中的语法糖 等价于 ;;
    • es6中 {…props} 等价于复制一份props, 而且数据不会相互影响,, 常用于给对象增加属性, 如 var obj = {…props, ‘foo’:’bar’} ,, 这里的… 展开的效果是 key:value的形式
    • … 运算符一般是用于数组较多,,还有一种用于形参(叫剩余运算符)
  • <Component {…this.props}/>
    • 这个是用于类组件中

hook

32课 Redux单向数据流 React-router4单页应用

  • 上节作业 createContext的实现(见该节pdf),体会下闭包

箭头函数return的简写形式

1
2
3
4
5
6
7
 一般写法 ()=>{},,参数只有一个时可以省略(), 函数体只有一句话时可以省略{},且默认是return的
const mapStatetoProps = state=>{
return {num: state} // {}中要明确写上是否return,不会默认return
}

//可以简写为: 当return的是{}包裹的对象时,加上()代表一个整体 return
const mapStatetoPropsstate=>({num: state}),,因为后面直接return数据时可以不用{},但是return的是对象,所以用()包裹,不用写return

vuex redux 修改数据对比(单向数据流)

  • 单向数据流: 修改数据时是一份新的数据,比如 给state 增加name属性redux的写法 {…state, name:’ccb’},相当于复制原来的state给新的state再添加属性,

    • {…state, name:’ccb’} 相当于 Object.assign({},state,{name:’ccb’})
  • vuex的写法的就state.name=‘ccb’ // state还是原来的state

redux-logger

  • F12会记录每次dispatch的action

路由

  • HashRouter和BrowserRouter 相当于vue是否使用model:history
  • 最后半小时原理 todo

33 Redux单向数据流 React-router4单页应用

umi

  • 单页应用

  • 安装后,package.json启动脚本修改为umi

    1
    2
    3
    4
    5
    "scripts": {
    "start": "umi dev",
    "build": "umi build",
    "test": "echo \"Error: no test specified\" && exit 1"
    },
  • antd layout this.props.children

    • 联系render-props对比下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class KLayout extends React.Component{
    render(){
    return <Layout>
    <Sider>
    侧边栏
    </Sider>
    <Layout>
    <Header>头部信息</Header>
    <Content>
    {this.props.children} // 外界使用Klayout,Klayout中的节点,相当于vue中的slot,,layout是最外层的路由
    </Content>
    <Footer>{this.props.children}</Footer>
    </Layout>

    </Layout>
    }
    }
  • umi 命令创建页面

    npm i -g umi 需要全局安装

    项目路径下 npm g page login 自动生成login.js 和login.css

  • 支持less ,,sass需要loader ?

dva

  • model中多个数据用命名空间区分 todo
  • dva connect 会默认提供dispatch , this.props.dispatch,, 数据的话可以自己映射dva默认映射dispatch到props, 直接使用dispatch调用想用namespace/reducer,,不需要单独映射

34 react 项目实战

  • component文件夹放可以复用的组件, pages放的是业务页面, layout是布局

    和vue中component和views文件夹的意义差不多

  • 进度条npm install nprogress –save

  • 手写promise vue原理 vue组件设计 react 原理 react组件设计 redux原理 vue/react区别

35 react 项目实战

  • 拦截器 全局文件执行
  • 多model
  • 异步effects generator
  • umi/router js路由跳转 router.push
  • 进度条设置在拦截器中 请求时开始和响应时结束,, 有个微交互的过程
  • ant design pro === vue admin 适合做cms
  • ant design pro exception处理
  • ant pro tag 栅格系统 flex布局 card
  • 作业: 主页默认加载全部商品:使用 componentWillReceiveProps,,组件dispatch后,props会传递变更的数据

36 react 项目实战

  • antd Skeleton 骨架屏
  • react请求数据一般放componentDidMount里, 加上初次render, 要render两次
  • KHeader: antd-pro noticeIcon购物车
  • 登录状态的逻辑, 某些业务逻辑需要登录的状态下, 比如购物时需要校验token, 未登录跳转到登录页或显示登录按钮,已经登录显示退出按钮等;; 首页可以不用登录, 但购买时需要登录
  • react 动画
    • npm i react-motion –save 跨平台 推荐;; about组件中 演示
    • react-tran’sition-group
  • css属性如fontSize html style中用驼峰

37 源码

  • vscode调试源码,,精简版源码
  • createelement domdiff
  • redux原理 react-redux原理 单向数据流
  • hook 函数组件管理state
  • dva router原理