1. 属性dangerouslySetInnerHTML直接渲染字符串为html
2. React.Children.map或.forEach或.count都是React提供的便利的方法,用以处理children。
3. 组件间的通信
- 父组件向子组件通信用props,
- 子组件向父组件通信用回调函数
- 跨组件通信得用全局事件,广播
4. 组件所有生命周期及属性
import React, { Component, PropTypes } from 'react'
class App extends Component {
static propTypes = {
// 类型约束
}
static defaultProps = {
// 默认props
}
constructor(props) {
super(props);
this.state = {
//初始化state
}
}
//以下生命周报将会依次执行
componentWillMount() {
// 组件将挂载前执行
// 挂载前初始化动作
}
componentDidMount() {
// 组件挂载后执行
// 有时需要挂载后才能获取的属性,比如宽高,位置
}
componentWillReceiveProps(nextProps) {
// 组件将会接收到从父组件传来的新props
// 即组件的props变化后,根据新props更新state
// this.setState({})
}
sholdComponentUpdate(nextProps,nextState) {
// 组件是否要更新并重新渲染
// 默认是每次props,state变化就重新渲染,但此方法允许我们对新props或新state进行判断,识别,返回false则会阻止渲染,提高性能
// return true
}
componentWillUpdate(nextProps,nextState) {
// 组件将要更新
// 我觉得this.props是旧props,nextProps是新props, state同
// 以便我们能根据新旧值进行一些处理
}
componentDidUpdate(prevProps,prevState) {
// 组件已经更新
// 我觉得this.props是新props,prevProps是旧props, state同
// 以便我们能根据新旧值进行一些处理
}
componentWillUnmount() {
// 组件卸载前执行
// 执行清理,回收
}
}
5. 无状态组件和有状态组件
- 直接返回html的函数是无状态组件
- class构造的是有状态组件
无状态组件不会有生命周期
使用Recompose库的pure方法可以传入无状态组件,包装返回有状态组件
6. 在react使用refs获取组件挂载后的DOM实例,可添加原生事件,但要记得在将要卸载前移除原生事件。
7. 表单
-
受控组件要有value或checked 和 onChange
input和select 受控组件要有value属性
option 有selected属性
radio和checkbox 受控组件要有checked属性 -
非受控组件要有defaultValue或defaultChecked 用ref操作原生DOM
defaultValue和defaultCheced 只会渲染一次,在后续的渲染时并不起作用
8.样式
1.样式中的像素值
以px为单位的样式,可以不用加px,直接使用数字
2.react中的classname
实际就是普通元素中的class,接受字符串参数,普通用法得自己拼接字符串
可以使用classname库,像vue那样根据布尔值决定是否显示相应的class
const buttonClass = classname({active: true, disabled: true})
-
scss中的变量可以输出到js
import style form 'config.scss'; console.log(style.primary) // #eee
使用css modules
-
1.使用
import style from './Button.css';
<button className=${styles.normal}>1</button>
相当于<button class="button--normal-ab234d">1</button>
css modules会自动添加hash,以避免样式重复 -
2.css modules的css文件中写样式,默认是local
.normal{} 等同于 :local(.normal){} // 如果想定义全局样式 :global(.btn){} // 如果想定义多个全局样式 :global{ .btn{} .btn2{} } //如果想复用样式,使用composes .base{} .normal{ composes: base;//这样就能插入base的样式 } .normal{ composes: $base from './settings.css';//这样就能从别的文件中插入base的样式 }
9.react组件构建的三种方法
- React.createClass()
const Button = React.createClass({
getDefaultProps(){
return {
color: 'blue',
text: 'confirm'
};
},
render(){
const {color,text} = this.props;
return (
<button className={'btn btn-${color}'}>{text}</button>
)
}
})
这个是最原始,兼容性最高的创建方法
getDefaultProps会返回color,text的值给 this.props
在渲染时,再把this.props的值解构赋值给{color,text}。这样现在才能使用这两个变量
每次使用Button组件时,都会调用该方法生成实例
- 2.ES6 classes 的写法
import React, { Component } from 'react';
class Button extends Component {
constructor(props){
super(props);
}
static defaultProps = {
color: 'blue',
text: 'confirm'
};
render(){
const {color,text} = this.props;
return (
<button className={'btn btn-${color}'}>{text}</button>
)
}
}
static defaultProps定义默认属性值,contructor初始化构造(如果属性有默认值,则引用默认值,如果属性在组件上定义了,则引用定义的),最后渲染时,也仍然需要把属性解构赋值出来const {color,text} = this.props;这样才能在组件中使用上这些变量
每次使用Button组件时,都会调用该方法生成实例
- 3.无状态函数
function Button({color='blue',text='confirm'}){
return (
<button className={'btn btn-${color}'>{text}</button>
)
}
无状态组件只传入props,和context两个参数,不存在state,也就没有生命周期,但仍然还有propTypes和defaultProps静态方法
在合适的情况下,能使用无状态函数就使用无状态函数,因为无论这个组件调用多少次,他始终保持着一个实例。
10.props中可以传递组件作为属性
function Button({color='blue',childComp='<div>子组件</div>'}){
return (
<button className={'btn btn-${color}'>{childComp}</button>
)
}
11.react中事件和html中的事件绑定区别
react中元素事件得用onClick这样的驼峰式写法
html中的元素事件是用onclick全小写的写法
react中支持各种属性值
onClick={this.handleClick}
而html中只支持
onclick="handleClick()";
12.react中的事件是直接绑定在最外层,然后由最外层分配事件给子组件
13.react中绑定事件的三种方法
- 1.自动绑定
class App extends Component {
static handleClick(e, arg) {
console.log(e, arg);
}
render() {
return (
<div className="App">
<button onClick={App.handleClick.bind(this, 'text1')}>1</button>
</div>
);
}
}
- 2.在构造器中绑定
class App extends Component {
contructor(props){
super(props);
this.handleClick = this.handleClick.bind(this);
}
static handleClick(e, arg) {
console.log(e, arg);
}
render() {
return (
<div className="App">
<button onClick={this.handleClick}>1</button>
</div>
);
}
}
- 3.箭头函数(默认绑定当前环境的this)
class App extends Component {
handleClick(e, arg)=>{
console.log(e, arg);
}
render() {
return (
<div className="App">
<button onClick={this.handleClick}>1</button>
</div>
);
}
}
14.mixin
就是把外库属性混入当前组件
React.createClass({
mixins: [xxx],
render(){}
})
或安装minxin装饰插件
@minxin(PureRender, Theme)
class MyComponent extends Component {
}
mixin缺点
- 破坏原有组件封装
- 命名冲突
- 增加复杂性
所以最新的react已经建议不使用mixin,而是换用高阶组件
15. 高阶组件
-
属性代理
-
控制props
-
通过refs使用引用
-
抽象state
我觉得就是通过某个函数或装饰器或外层组件包裹低级组件,给低级组件添加增强属性,增强组件。
16. lodash.js
Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库
17.Immutable.js
Immutable库,PureRender库,react-immutable-render-mixin, react-css-modules, react motion
不可变数据,高效对比
17.1 React性能优化总结
https://segmentfault.com/a/1190000007811296
// 在react的checkbox组件中测试
// 继承React.Component,输出13个1和13个2
// 继承React.PureComponent,输出13个1和6个2
// 减少了一半的重复渲染
componentWillReceiveProps(props) {
console.log(1)
}
componentDidUpdate(prevProps, prevState) {
console.log(2)
}
18.循环迭代组件时key属性的作用
key用来标识当前组件的唯一性
- 错误的做法,使用序号或随机值作为key, 低效
- 正确的做法,使用数据中的唯一id或唯一值作为key,高效
19. react-addons-perf react性能测试
20.vivus.js SVG线条动画
21.css动画
React 提供了一个 ReactTransitionGroup 插件作为动画的底层API,和一个 ReactCSSTransitionGroup 用于轻松实现基础的CSS动画和过渡。
https://github.com/reactjs/react-transition-group
使用方法基本和vue差不多
22.three.js 3D动画
23.react-motion库,使用js实现动画,更加优美的缓动
24.自动化测试
- jest
- 浅渲染机制(只渲染和测试组件第一层,子组件应该在子组件中测试)
- 全渲染机制(完整渲染后,再测试)
- JSDOM: js 模拟DOM环境
- Cheerio: 类似JSDOM,类似JQuery语法
- Karma: 真实浏览器中执行测试,使用真实的DOM
其中Cheerio即Enzyme是Airbnb开源的React组件测试框架,这个可以优先和重点看看。
网友评论