Hank's Blog

耕种思考的自留地

0%

React 组件 API

React 组件 API 中有以下7个常用方法:

  • 设置状态:setState
  • 替换状态:replaceState
  • 设置属性:setProps
  • 替换属性:replaceProps
  • 强制更新:forceUpdate
  • 获取DOM节点:findDOMNode
  • 判断组件挂载状态:isMounted

setState

1
setState(nextState[, callback])
  • nextState:一个对象。将要设置的新状态,该状态会和当前的state合并
  • callback:回调函数。该函数会在setState设置成功,且组件重新渲染后调用

replaceState

1
replaceState(nextState[, callback])
  • nextState:一个对象。将要设置的新状态,该状态会替换当前的state。
  • callback:回调函数。该函数会在replaceState设置成功,且组件重新渲染后调用。

setProps

1
setProps(nextProps[, callback])
  • nextProps:一个对象。将要设置的新属性,该状态会和当前的props合并
  • callback:回调函数。该函数会在setProps设置成功,且组件重新渲染后调用

replaceProps

1
replaceProps(nextProps[, callback])
  • nextProps:一个对象。将要设置的新属性,该属性会替换当前的props。
  • callback:回调函数。该函数会在replaceProps设置成功,且组件重新渲染后调用。

forceUpdate

1
forceUpdate([callback])
  • callback:回调函数。该函数会在组件render()方法调用后调用。

forceUpdate()方法会使组件和子组件调用自身的render()方法重新渲染组件。但是,组件重新渲染时,依然会读取this.props和this.state,如果状态没有改变,那么React只会更新DOM。

一般来说,应该尽量避免使用forceUpdate(),而仅从this.props和this.state中读取状态并由React触发render()调用。

findDOMNode

1
DOMElement findDOMNode()

如果组件已经挂载到DOM中,该方法返回对应的本地浏览器 DOM 元素。当render返回null 或 false时,this.findDOMNode()也会返回null。

isMounted

1
bool isMounted()

返回值:true或false,表示组件是否已挂载到DOM中。可以使用该方法保证了setState()和forceUpdate()在异步场景下的调用不会出错。

Read more »

起步

1
2
3
4
5
6
7
8
9
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
<script>
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
</script>

JSX

React 使用 JSX 来替代常规的 JavaScript。JSX中有如下注意点:

  • 变量需要包含在{}
  • 不能使用if else,可以使用三元表达式来替代
  • 注释需要写在花括号中
  • JSX 允许在模板中插入数组,数组会自动展开所有成员
  • 在添加属性时, class 属性需要写成 className ,for 属性需要写成 htmlFor ,因为 class 和 for 是 JavaScript 的保留字
  • 组件类只能包含一个顶层标签
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    var myStyle = {
    fontSize: 100,
    color: '#FF0000'
    };
    var arr = [
    <h1>菜鸟教程</h1>,
    <h2>学的不仅是技术,更是梦想!</h2>,
    ];
    ReactDOM.render(
    <div>
    <h1>{1 + 2}</h1>
    <h2>{i == 1 ? 'True!' : 'False'}</h2>
    <p style = {myStyle}>react is cool!</p>
    <p>{arr}</p>
    {/*注释...*/}
    </div>
    ,
    document.getElementById('example')
    );
    React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes)。React 的 JSX 使用大、小写的约定来区分本地组件的类和 HTML 标签。
    要渲染 HTML 标签,只需在 JSX 里使用小写字母的标签名。
    1
    2
    var myDivElement = <div className="foo" />;
    ReactDOM.render(myDivElement, document.getElementById('example'));
    要渲染 React 组件,只需创建一个大写字母开头的本地变量。
    1
    2
    3
    var MyComponent = React.createClass({/*...*/});
    var myElement = <MyComponent someProperty={true} />;
    ReactDOM.render(myElement, document.getElementById('example'));
    Read more »

ES6 加强了对 Unicode 的支持,并且扩展了字符串对象。
ES6 为字符串添加了遍历器接口,使得字符串可以被for...of循环遍历。

1
2
3
4
5
6
for (let codePoint of 'foo') {
console.log(codePoint)
}
// "f"
// "o"
// "o"

charAt()

ES5 对字符串对象提供arAt方法,返回字符串给定位置的字符。该方法不能识别码点大于0xFFFF的字符。

1
2
'abc'.charAt(0) // "a"
'𠮷'.charAt(0) // "\uD842"

repeat()

repeat方法返回一个新字符串,表示将原字符串重复n次。参数如果是小数,会被取整。参数不能是小于等于-1的负数或Infinity

1
2
3
4
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(-0.9) // ""
'na'.repeat(2.9) // "nana"
Read more »

ES6 允许按照一定模式,从数组对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

数组的解构赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

let [x, y, z] = new Set(['a', 'b', 'c']);
x // "a"

如果解构不成功,变量的值就等于undefined。解构赋值允许指定默认值。

1
2
3
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x = 1] = [undefined]; // x = 1
let [x = 1] = [null]; // x = null

上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined

Read more »

要实现继承先定义一个父类

1
2
3
4
5
6
7
8
9
function Animal (name) {
this.name = name || 'Animal';
this.sleep = function(){
console.log(this.name + '正在睡觉!');
}
}
Animal.prototype.eat = function(food) {
console.log(this.name + '正在吃:' + food);
};

原型链继承

核心: 将父类的实例作为子类的原型。

1
2
function Cat () {}
Cat.prototype = new Animal('cat');

构造继承

核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类。

1
2
3
4
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
Read more »

在vue中给元素添加类名非常灵活,主要分为三种形式。

对象的形式

1
2
3
<template>
<div :class="{jd: true, jd2: false}"></div>
</template>

数组的形式

1
<div :class="['jd','jd2'}"></div>

注意数组中的类名需要加单引号,数组里也可以用对象,对象的键名如果是不带-的可以不加单引号。

1
<div :class="[{jd: true}, {'jd-2': true}, 'jd2'}"></div>

也可以在数组中使用三元表达式

1
2
3
4
5
<div :class="[
(item.jd === '增发预案' || item.jd === '已经实施') ? 'jd' :
(item.jd === '董事会预案' || item.jd === '审核通过') ? 'jd2' :
(item.jd === '增发失败') ? 'jd3' : 'jd4'
]">{{item.jd}}</div>
Read more »

ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。

1
2
3
4
5
6
7
8
const map = new Map([
['name', '张三'],
['title', 'Author']
]);

const map2 = new Map()
.set('yes', true)
.set('no', false);

Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。这就解决了同名属性碰撞(clash)的问题,我们扩展别人的库的时候,如果使用对象作为键名,就不用担心自己的属性与原作者的属性同名。
如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键,比如0-0就是一个键,布尔值true和字符串true则是两个不同的键。另外,undefinednull也是两个不同的键。虽然NaN不严格相等于自身,但 Map 将其视为同一个键。

map实例的属性

  • Map.prototype.size 返回map实例的成员总数。

map实例的操作方法

  • set(key, value) set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。
  • get(key) get方法读取key对应的键值,如果找不到key,返回undefined。
  • has(key) has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
  • delete(key) delete方法删除某个键,返回true。如果删除失败,返回false。
  • clear() clear方法清除所有成员,没有返回值。
Read more »

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。

1
const s = new Set([1, 2, 3, 4, 4]); // [[1, 2, 3, 4]

由此可以导出一种简单的数组去重方法

1
2
3
function dedupe(arr) {
return [...new Set(arr)]
}

Array.from方法可以将 Set 结构转为数组,所以数组去重也可以这么写

1
2
3
function dedupe(arr) {
return Array.from(new Set(arr));
}

set实例的属性

  • Set.prototype.size 返回Set实例的成员总数。

set实例的操作方法

  • add(value) 添加某个值,返回 Set 结构本身。
  • delete(value) 删除某个值,返回一个布尔值,表示删除是否成功。
  • has(value) 返回一个布尔值,表示该值是否为Set的成员。
  • clear() 清除所有成员,没有返回值。
Read more »

reduce() 是 ECMAScript5 规范中出现的数组方法。一般而言,可以通过reduce方法实现的逻辑都可以通过forEach方法来实现。根据规范: 在一个空数组上应用reduce会抛初始化错误的异常TypeError

语法

1
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
参数 描述
function(total,currentValue, index,arr) 必需。用于执行每个数组元素的函数。
total 必需。初始值, 或者计算结束后的返回值。
currentValue 必需。当前元素
currentIndex 可选。当前元素的索引
arr 可选。当前元素所属的数组对象。
initialValue 可选。传递给函数的初始值

例子

1
2
3
4
5
var numbers = [25, 14, 16, 5];
function getSum(total, item) {
return total + item;
}
console.log(numbers.reduce(getSum)); // 60
1
2
3
4
5
6
var items = [7, 12.1, 100.3];
var reducer = function add(total, item) {
total.sum = total.sum + Math.round(item);;
return total;
};
console.log(items.reduce(reducer, {sum: 0})); // {sum:119}

reduce 方法可用于解析对象链式属性

1
2
3
4
5
6
7
var data = {
num: {
a: 12,
b: 13
}
}
'num.a'.split('.').reduce((obj, name) => obj[name], data) // 12

也可以用于函数式编程

1
2
3
4
5
6
7
function compose(...funcs) {
if (funcs.length === 0) return arg => arg
if (funcs.length === 1) return funcs[0]
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
const func = compose(fn1,fn2,fn3) // (i) => fn1(fn2(fn3(i)))
func(5) // ((5 % 2) + 2) * 2 = 6

indexOf() 方法可返回某个指定的值在字符串或数组中首次出现的位置,对象没有这个方法

语法

1
stringObject.indexOf(searchvalue,fromindex)
  • searchvalue 必需。规定需检索的字符串值。
  • fromindex 可选的整数参数。规定在字符串中开始检索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略该参数,则将从字符串的首字符开始检索。

indexOf() 方法对大小写敏感!
如果要检索的字符串值没有出现,则该方法返回 -1。
indexOf()相对的方法是lastIndexOf()

应用拓展

1
2
3
4
5
6
7
8
9
10
11
12
13
let str2 = 'qwertyuioasdfghjke';
console.log(str2.indexOf('wer')); // 1
console.log(str2.indexOf('e')); // 2

let arr2 = [{aa: 13}, [12, 99], 96, '55', undefined, null];
console.log(arr2.indexOf({aa: 13})); // -1
console.log(arr2.indexOf([12, 13])); // -1
console.log(arr2.indexOf(96)); // 2
console.log(arr2.indexOf('55')); // 3
console.log(arr2.indexOf('96')); // -1
console.log(arr2.indexOf(55)); // -1
console.log(arr2.indexOf(undefined)); // 4
console.log(arr2.indexOf(null)); // 5

indexOf() 可以用来确定数组中是否存在某个基本类型的值或者null, 从上面的例子可以发现,indexOf无法确定数组和对象的存在,因为

1
2
{} == {} // false
[] == [] // false

但是如果是引用地址就可以确定是否存在

1
2
3
4
5
let obj = {aa: 13};
let arr = [12, 99];
let arr2 = [obj, arr, 96, '55', undefined, null];
console.log(arr2.indexOf(obj)); // 0
console.log(arr2.indexOf(arr)); // 1