# 组件扩展

从本节开始，我们来介绍如何使用Typescript和React来编写RCRE扩展组件。


## 调用API

### 采用script标签引入

在window变量中，必然会有RCRE这个全局变量。

```javascript
console.log(window.RCRE);
```

### 采用npm包安装的方式
所有的API都在rcre-core这个模块内部。

```javascript
import {Render} from 'rcre-core';
```

## HelloWorld

我们来自己写一个超简单的组件来开始吧。

当在配置文件中使用这个组件的时候，它会显示出helloworld

```typescript
import {BasicConfig, BasicContainer, BasicContainerPropsInterface, componentLoader} from 'rcre-core';
import * as React from 'react';

export class HelloWorldConfig extends BasicConfig {}

export class HelloWorldPropsInterface extends BasicContainerPropsInterface {
    info: HelloWorldConfig;
}

class HelloWorld extends BasicContainer<HelloWorldPropsInterfaced, {}> {
    render() {
        return <div>helloworld</div>;
    }
}
 
componentLoader.addComponent('helloworld', HelloWorld, HelloWorldPropsInterface);
```

RCRE本身提供了开发扩展组件需要的接口定义，在开发组件的时候，直接扩展提供的基础组件即可。

当react组件完成之后，调用componentLoader.addComponent函数来把写好的组件导入到RCRE内。

这样，就可以在配置中使用这样的配置来使用这个组件了。

```_raw_json
{
    "type": "helloworld"
}
```

## 读取配置中的值

接下来我们来介绍如何在组件中，读取在配置中写入的值。

在组件中，可以直接使用this.props.info来获取当前组件的json信息，例如：

```_raw_json
{
    "type": "helloworld",
    "name": "andycall"
}
```

对于helloworld组件上面的name属性，可以使用this.props.info.name来读取。

## 读取采用ExpressionString的值

如果组件中一些属性是需要用ExpressionString动态计算出来的，可以使用`this.getPropsInfo`这个函数来进行转化，然后再读取。

例如：
```_raw_json
{
    "type": "container",
    "model": "demo",
    "data": {
        "name": "andycall"
    },
    "children": [{
        "type": "helloworld",
        "name": "#ES{$data.name}"
    }]
}
```

在组件中，想获取$data.name计算之后的值：

```javascript
let info = this.getPropsInfo(this.props.info);
console.log(info.name) // andycall
```

### 手动指定props
`this.getPropsInfo`底层是从`this.props`来获取必要的信息，如果想从别的地方获取，比如componentWillReceiveProps里面的nextProps。

可以使用第二个参数

```javascript
componentWillReceiveProps(nextProps) {
   let info = this.getPropsInfo(nextProps.info, nextProps);
}
```

### 配置属性白名单
在默认情况下, `this.getPropsInfo`函数会处理this.props.info这个对象第一层级的所有带有ExpressionString的属性。

如果需要忽略掉某些属性值，可以使用第三个参数：

例如：

```_raw_json
{
    "type": "container",
    "model": "demo",
    "data": {
        "name": "andycall"
    },
    "children": [{
        "type": "helloworld",
        "name": "#ES{$data.name}",
        "ignoredProps": "#ES{$data.name}"
    }]
}
```

在调用`this.getPropsInfo`的时候，指定忽略ignoredProps，就会保留原有的ExpressionString字符串。

```javascript
let info = this.getPropsInfo(this.props.info, this.props, ['ignoredProps']);
console.log(info.name) // andycall
console.log(info.ignoredProps) // #ES{$data.name}
```

### 深度处理所有的属性
在默认情况下，`this.getPropsInfo`函数不会处理配置中嵌套的对象的ExpressionString值。
例如：

```_raw_json
{
    "type": "helloworld",
    "nest": {
        "name": "#ES{$data.name}"
    }
}
```

在处理之后，`info.nest.name`依然是#ES{$data.name}。

如果想处理嵌套的情况，可以在调用函数的时候，把第四个参数设置成true

```javascript
let info = this.getPropsInfo(this.props.info, this.props, [], true);
console.log(info.nest.name) // andycall
```
