高阶组件是什么?如何理解?
高阶组件就是一个对普通组件的包装,并返回一个新的组件。本质上就是一个函数。
react-redux connect==>容器组件 connect()(ui组件)
withRouter withRouter(App)
https://www.jb51.net/article/137272.htm
高阶组件就是接受一个组件作为参数,返回一个相对增强性的组件的函数
作用:
1、属性代理---主要进行组件的复用
2、反向集成---主要进行渲染的劫持
高阶组件是一个以组件为参数并返回一个新组件的函数。HOC 运行你重用代码、逻辑和引导抽象。
最常见的可能是 Redux 的 connect 函数。如果你发现你在不同的地方写了大量代码来做同一件事时,
就应该考虑将代码重构为可重用的 HOC。
高阶函数与高阶组件
1. 高阶函数
1). 一类特别的函数
a. 接受函数类型的参数
b. 返回值是函数
2). 常见
a. 定时器: setTimeout()/setInterval()
b. Promise: Promise(() => {}) then(value => {}, reason => {})
c. 数组遍历相关的方法: forEach()/filter()/map()/reduce()/find()/findIndex()
d. 函数对象的bind()
e. Form.create()() / getFieldDecorator()()
3). 高阶函数更新动态, 更加具有扩展性
2. 高阶组件
1). 本质就是一个函数
2). 接收一个组件(被包装组件), 返回一个新的组件(包装组件), 包装组件会向被包装组件传入特定属性
3). 作用: 扩展组件的功能
3. 高阶组件与高阶函数的关系
高阶组件是特别的高阶函数
接收一个组件函数, 返回是一个新的组件函数
day02
Component与PureComponent
1). Component存在的问题?
a. 父组件重新render(), 当前组件也会重新执行render(), 即使没有任何变化
b. 当前组件setState(), 重新执行render(), 即使state没有任何变化
2). 解决Component存在的问题
a. 原因: 组件的shouldcomponentUpdate()默认返回true, 即使数据没有变化render()都会重新执行
b. 办法1: 重写shouldComponentUpdate(), 判断如果数据有变化返回true, 否则返回false
c. 办法2: 使用PureComponent代替Component
d. 说明: 一般都使用PureComponent来优化组件性能
3). PureComponent的基本原理
a. 重写实现shouldComponentUpdate()
b. 对组件的新/旧state和props中的数据进行浅比较, 如果都没有变化, 返回false, 否则返回true
c. 一旦componentShouldUpdate()返回false不再执行用于更新的render()
PureComponent 纯组件 自带shouldComponentUpdate,可以对props进行浅比较。 浅拷贝、深拷贝
发现后面的props与前面的props一样,就不会进行render了。 (引用类型地址相同的话,不会render!)
https://www.cnblogs.com/clover77/p/9394514.html
class Test extends React.PureComponent{ <div><Test a={10}/></div>
constructor(props){
super(props);
}
render(){
return <div>hello...{this.props.a}</div>
}
}
react 组件的划分业务组件技术组件?
1.根据组件的职责通常把组件分为 UI 组件和容器组件。
2.UI 组件负责 UI 的呈现,容器组件负责管理数据和逻辑。
3.两者通过 React-Redux 提供 connect 方法联系起来。
受控组件与非受控组件的区别
受控组件: 受到数据的控制。组件的变化依靠数据的变化,数据变化了,页面也会跟着变化了。
<input value={this.state.value}/>
输入框收到数据的控制,数据只要不变化,input框输什么都不行。
非受控组件: 直接操作dom,不做数据的绑定。通过refs来获取dom上的内容进行相关的操作。
<input ref={el=>this.el=el}/>
react==>数据驱动是react核心。
React 中有三种构建组件的方式
- React.createClass()、
- ES6 class
- 无状态函数。
类组件与函数式组件区别?
1.类组件不仅允许你使用更多额外的功能,如组件自身的状态和生命周期钩子,
也能使组件直接访问 store 并维持状态
2.当组件仅是接收 props,并将组件自身渲染到页面时,该组件就是一个
'无状态组件(stateless component)',可以使用一个纯函数来创建这样的组件。
这种组件也被称为哑组件(dumb components)或展示组件
3.如果您的组件具有状态( state ) 或 生命周期方法,请使用 Class 组件
包含表单元素的组件将会在 state 中追踪输入的值,并且每次调用回调函数时,
如 onChange 会更新 state,重新渲染组件。一个输入表单元素,它的值通过 React 的这种方式来控制,
这样的元素就被称为"受控元素"。
组件是什么?类是什么?类被编译成什么?
模块:在webpack中,通过import引入的文件叫做模块。(js/css/png)
函数:是一些功能的合集。
组件:指的是页面的某一部分。
在 React 当中 Element 和 Component 有何区别?
React Element 是描述屏幕上所见内容的数据结构,是对于 UI 的对象表述。
典型的 React Element 就是利用 JSX 构建的声明式代码片然后被转化为 createElement 的调用组合。
React Component 是一个函数或一个类,可以接收参数输入,并且返回某个 React Element
在react中是否封装过组件?封装组件需要注意的地方?
常用封装组件用到的东西1、propTypes 限制外部数据的类型2、defaultProps 设置默认的外部数据3、父传子 子传父 context 等传值方式4、高阶组件封装组件的时候一定要注意组件的复用性,灵活性
如何接收组件内部的标签/内容
通过this.props.children
Login的静态组件
1). 自定义了一部分样式布局
2). 使用antd的组件实现登陆表单界面
Form / Form.Item
Input
Icon
Button
LeftNav组件
1). 使用antd的组件
Menu / Item / SubMenu
2). 使用react-router
withRouter(): 包装非路由组件, 给其传入history/location/match属性
history: push()/replace()/goBack()
location: pathname属性
match: params属性
3). componentWillMount与componentDidMount的比较
componentWillMount: 在第一次render()前调用一次, 为第一次render()准备数据(同步)
componentDidMount: 在第一次render()之后调用一次, 启动异步任务, 后面异步更新状态重新render
4). 根据动态生成Item和SubMenu的数组
map() + 递归: 多级菜单列表
reduce() + 递归: 多级菜单列表
5). 2个问题?
刷新时如何选中对应的菜单项?
selectedKey是当前请求的path
刷新子菜单路径时, 自动打开子菜单列表?
openKey是 一级列表项的某个子菜单项是当前对应的菜单项
Header组件
1). 界面静态布局
三角形效果
2). 获取登陆用户的名称显示
MemoryUtils
3). 当前时间
循环定时器, 每隔1s更新当前时间状态
格式化指定时间: dateUtils
4). 天气预报
使用jsonp库发jsonp请求百度天气预报接口
对jsonp请求的理解
5). 当前导航项的标题
得到当前请求的路由path: withRouter()包装非路由组件
根据path在menuList中遍历查找对应的item的title
6). 退出登陆
Modal组件显示提示
清除保存的user
跳转到login
7). 抽取通用的类链接按钮组件
通过...透传所有接收的属性: <Button {...props} /> <LinkButton>xxxx</LinkButton>
组件标签的所有子节点都会成为组件的children属性
Category组件
1. 使用antd组件构建分类列表界面
Card
Table
Button
Icon
ProductHome组件
1). 分页显示
界面: <Card> / <Table> / Select / Icon / Input / Button
状态: products / total
接口请求函数需要的数据: pageNum, pageSize
异步获取第一页数据显示
调用分页的接口请求函数, 获取到当前页的products和总记录数total
更新状态: products / total
翻页:
绑定翻页的监听, 监听回调需要得到pageNum
异步获取指定页码的数据显示
2). 搜索分页
接口请求函数需要的数据:
pageSize: 每页的条目数
pageNum: 当前请求第几页 (从1开始)
productDesc / productName: searchName 根据商品描述/名称搜索
状态: searchType / searchName / 在用户操作时实时收集数据
异步搜索显示分页列表
如果searchName有值, 调用搜索的接口请求函数获取数据并更新状态
3). 更新商品的状态
初始显示: 根据product的status属性来显示 status = 1/2
点击切换:
绑定点击监听
异步请求更新状态
4). 进入详情界面
history.push('/product/detail', {product})
5). 进入添加界面
history.push('/product/addupdate')
ProductDetail组件
1). 读取商品数据: this.props.location.state.product
2). 显示商品信息: <Card> / List
3). 异步显示商品所属分类的名称
pCategoryId==0 : 异步获取categoryId的分类名称
pCategoryId!=0: 异步获取 pCategoryId/categoryId的分类名称
4). Promise.all([promise1, promise2])
返回值是promise
异步得到的是所有promsie的结果的数组
特点: 一次发多个请求, 只有当所有请求都成功, 才成功, 并得到成功的数据,一旦有一个失败, 整个都失败