[Airbnb React/JSX 编码规范](https://github.com/JasonBoy/javascript/blob/master/react/README.md)

### ant-design-pro 2.x踩坑手记（包含react） ###
- this.setState是异步的，所以在this.setState之后不能立刻得到最新的state，如果想设置完直接去拿修改过的state代码如下：
```javascript
this.state = {foo: 2};
this.setState({foo: 123}, ()=> {
    console.log(foo);
    // 123
});
```

- antd组件默认属性（例如initialValue、defaultValue、defaultFileList）只会被初始化一次），直接修改不会重新渲染，如果需要重新渲染则需要修改另外的属性值（例如setFieldsValue、value、fileList）
- setState直接修改数组或者对象的某个值是不会导致渲染的代码入下：
```javascript
//❌
//获取父组件的数据
  	var arr = this.state.tags;
	//子组件中传来的数据数组
        for(var i=0; i<rows.length; i++){

	    //isAddData方法是判断数据存不存在
            if(this.isAddData(arr, rows[i])){
                arr.unshift(rows[i]);
            }

        }

        this.setState({ tags: arr });
```
```javascript
//✅
var arr = this.state.tags;
	//子组件中传来的数据数组
        for(var i=0; i<rows.length; i++){

	    //isAddData方法是判断数据存不存在
            if(this.isAddData(arr, rows[i])){
                arr.unshift(rows[i]);
            }

        }

        this.setState({ tags: [...arr] });
```
- 同一个页面多个子组件调用同一个接口，数据可能会导致出错问题

    **解决方案**: 用 state 定义一个 name: 设置 true/false,等待第一个接口加载完毕，再进行 第二次请求(建议设计组件的时候数据可以传入)
    
- 同一个接口需要点击多次，以最后一次请求为准，因为没有用 loading 才会 出现的数据回来了但是界面没有刷新数据

    **解决方案**:fetch 添加一个 type:’takeLatest’，(takeEvery（默认），takeLatest，throttle，watcher)代码如下：
```
effects: {
    fetch: [function* ({payload}, { call, put }) {
      yield put({
        type: 'changeLoading',
        payload: true,
      });
      const response = yield call(calendarMonth,payload);
      
      if(response){
        yield put({
          type: 'save',
          payload: response,
        });
      }
    }, {type: 'takeLatest'}]
}
```
注意：
watcher是指传入的任务函数就是一个watcher直接fork就好
throttle还要传入一个ms配置，这个ms代表着在多少毫秒内只触发一次同一类型saga任务
而takeEvery是不会限制同一类型执行次数
takeLatest只能执行一个同一类型任务，有执行中的再次执行就会取消

- 一个页面由多个组件组成 如何清空表单
如果通过emit分别触发各个组件，是可以实现的，但感觉代价太大

    **解决方案**：不需要emit，this.props.dispatch()，dispatch 是根据你里面设置的type内容 然后转发到指定的model的，所以你这边 要设置正确以后，在model那边才能接收到你发送的这条action，model中reducers 处理数据(同步)，effects接收数据(异步逻辑都要在effects里)，subscriptions 监听数据，代码如下

```javascript

this.props.dispatch({
  type: 'global/clearNotices',
  payload: type,
});


//models
export default {
  namespace: 'global',
  reducers: {
    clearNotices(state, action) {
      return {
        ...state,
        list: action.payload,
      };
    },
  },
};
  
```

- 单页面应用不要使用location.href这种方式会导致整页刷新，写类似a的跳转可以使用Link组建，如果js控制跳转，代码如下：

```javascript
import { routerRedux } from 'dva/router';

this.props.dispatch(routerRedux.push({
    pathname: '/user/register-result',
    state: {
      account,
    },
  }));
```
- 一个页面由多个组件组成，跨组件校验问题现在是通过Modal弹窗自己实现的 ，当组件保存按钮在别的组件里，需要带标识实现，实现特别复杂费劲（任务跟进是这样实现的）

- TABLE翻页 selectRow一定要清空

- 页面级的数据尽量不放store中，放在本文件state中，这种类似于session的 会带来bug

- 变量在不通层级中尽量不要重复，析构时候会指向不明

- this问题 箭头函数this是成员this，普通函数this指向函数本身，可以在钩子函数中赋值给自定义的_this

- route.js定义的组件中不要遗忘model的配置，否则dispatch的type的model没有配置则无法生效
代码如下：
```javascript
//dynamicWrapper(app,[model],() =>import('router路径'))
const routerConfig = {
    '/': {
      component: dynamicWrapper(app, ['user', 'login'], () => import('../layouts/BasicLayout')),
    },
```

- render中改state容易死循环

     **解决方案**：建议只有在componentWillMount,componentDidMount,componentWillReceiveProps方法中可以修改state值,在componentWillUpdate和componentDidUpdate中修改也可能导致无限循环调用


### 开发建议 ###
- 文件拆分和建文件夹归类 有的文件好几千行代码
- 文件组件化，现在很多文件都是为了实现自己的功能
- 根据是否需要高度的复用性，把组件划分为 Dumb 和 Smart 组件，约定俗成地把它们分别放到 components 和 containers 目录下。
    
    Dumb 基本只做一件事情 —— 根据 props 进行渲染。而 Smart 则是负责应用的逻辑、数据，把所有相关的Dumb（Smart）组件组合起来，通props 控制它们。
    
    Smart 组件可以使用 Smart、Dumb 组件；而 Dumb 组件最好只使用 Dumb 组件，否则它的复用性就会丧失。
    
    要根据应用场景不同划分组件，如果一个组件并不需要太强的复用性，直接让它成为 Smart 即可；否则就让它成为 Dumb 组件。

    还有一点要注意，Smart 组件并不意味着完全不能复用，Smart 组件的复用性是依赖场景的，在特定的应用场景下是当然是可以复用 Smart 的。而 Dumb 则是可以跨应用场景复用，Smart 和 Dumb 都可以复用，只是程度、场景不一样。
    
### 后端合作建议 ###
- 文档问题: 文档不提前给，文档基本只能看出来接口地址，参数返回全靠猜
- 有些适合后端处理的，都交给了前台。比如后端不知道怎么解析数组，前台需要把数组合并成a|b|c之类的字符串，还有可能是个多维数据。
- cas的权限管理是个坑，这块按理说应该后端解决, 对前端是透明的，现在都需要前端做大量适配工作
- 后端大量不友好的原子接口，前端展示某一块数据都要很多接口同时拿到获取数据，这种的后端代理这一层最好

