# 组件数据同步

本节，我们将介绍扩展组件如何把数据同步到container组件上。

RCRE本身也提供了很多支持数据同步的组件，比如Input，Select组件。

这些组件都有一个共同点，它们都有name属性。

name属性在这些组件中，都作为同步到container组件数据模型中的key。

所以，开发者在开发自己的扩展组件的时候，也应当遵循这种规范来开发。

## 从container组件获取数据

当组件有了name属性之后，在使用意义上就等同于在container的数据模型中有了一席之地。

我们就可以通过name属性来获取当前组件的值。

调用`this.getValueFromDataStore`函数就可以实现数据读取。

例如：

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

对于这样的一个组件配置，在组件代码中，就可以编写下面的逻辑来读取container组件中的数据。

```javascript
let info = this.getPropsInfo(this.props.info);
let value = this.getValueFromDataStore(info.name);
console.log(value);
```

## 判断组件是否处于container组件的内部

用户编写配置的时候，不一定会保证开发者写的组件一定会在container组件的内部。如果一个需要同步数据的组件被配置在没有container组件的地方，那么它是无法工作的，就需要提出错误信息。

开发者在编写组件的时候，可以通过`this.isUnderContainerEnv())函数来判断组件是否在container组件的内部。

## 同步数据到container组件

当需要同步数据的时候，开发者可以调用`this.props.$setData(info.name, value)`来同步新的数据到container组件上。

例如：

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

当这个组件的某一个事件被触发的时候，在回调函数内部同步数据到container上。

我们就可以编写下面的代码：

```typescript
onSomeThing(newValue: string) {
    let info = this.getPropsInfo(this.props.info);
    this.props.$setData(info.name, newValue);
}
```
## 设置初始值
可以同步数据的组件，可以设置初始同步到container组件的值。

组件在执行到componentWillMount这个生命周期的时候，就可以在组件渲染之前，把数据同步到container组件上。

一般使用defaultValue作为初始值的属性。

```javascript
componentWillMount() {
    let info = this.props.info;
    if (this.props.$setData && info.name && !_.isNil(info.defaultValue)) {
        const $setData = this.props.$setData;
        $setData(info.name, info.defaultValue);
    }
}
```

## 事件触发
配置中trigger属性使用的任何一个事件，都是在组件内部，通过`this.commonEventHandler`来进行触发的。

`this.commonEventHandler`是RCRE触发事件的唯一入口。

在组件内部，可以通过`this.commonEventHandler(eventName, eventArgs)`函数来触发事件

例如，举一个代理原生onClick事件的例子：

让helloworld组件支持点击操作

```_raw_json
{
    "type": "helloworld",
    "trigger": [{
        "event": "onClick",
        "targetCustomer": "$this",
        "params": {
            "status": "#ES{$args.status}"
        }
    }]
}
```

```javascript
render() {
    const onClickHandler = () => {
        this.commonEventHandler('onClick', {
            status: 'clicked'
        });
    };
    
    return <div onClick={onClickHandler}>helloworld</div>;
}
```

`this.commonEventHandler`的第二个参数是事件触发的参数，可以在trigger的params属性中使用$args这个引用来访问这个参数对象。 在注册是传入的`{status: 'clicked'}`就可以使用#ES{$args.status}来获取。
