ant-design-pro @connect 应该如何理解?

关于ant-design-pro中使用的DVA的@connect的疑惑

import React, { Component } from 'react';
import { connect } from 'dva';
import { Link } from 'dva/router';
import { Checkbox, Alert, Icon } from 'antd';
import Login from 'components/Login';
import styles from './Login.less';

const { Tab, UserName, Password, Mobile, Captcha, Submit } = Login;

@connect(({ login, loading }) => ({
  login,
  submitting: loading.effects['login/login'],
}))

已知

  1. 加载路由的时候,会动态加载当前文件下的model文件,也就是对应文件下的src/models/login.js
  2. connect 有两个参数,mapStateToProps以及mapDispatchToProps,一个将状态绑定到组件的props一个将方法绑定到组件的props

问题

  1. ({login, loading})=>({}) 这是一个函数,和connect 函数的两个参数不同,我应该如何理解这个写法?
  2. login和submitting这个怎么理解,是指绑定到submitting到组件的this.props里面吗? 那么他是如何把src/models/login.js 里面的effects触发的? 并且在组件中没有看到如何方法调用submitting
  3. loading.effects['login/login'] 这个方法应该如何理解?

src/router/login.js 全部代码

import React, { Component } from 'react';
import { connect } from 'dva';
import { Link } from 'dva/router';
import { Checkbox, Alert, Icon } from 'antd';
import Login from 'components/Login';
import styles from './Login.less';

const { Tab, UserName, Password, Mobile, Captcha, Submit } = Login;

@connect(({ login, loading }) => ({
  login,
  submitting: loading.effects['login/login'],
}))
export default class LoginPage extends Component {
  state = {
    type: 'account',
    autoLogin: true,
  };

  onTabChange = type => {
    this.setState({ type });
  };

  handleSubmit = (err, values) => {
    const { type } = this.state;
    if (!err) {
      this.props.dispatch({
        type: 'login/login',
        payload: {
          ...values,
          type,
        },
      });
    }
  };

  changeAutoLogin = e => {
    this.setState({
      autoLogin: e.target.checked,
    });
  };

  renderMessage = content => {
    return <Alert style={{ marginBottom: 24 }} message={content} type="error" showIcon />;
  };

  render() {
    const { login, submitting } = this.props;
    const { type } = this.state;
    return (
      <div className={styles.main}>
        <Login defaultActiveKey={type} onTabChange={this.onTabChange} onSubmit={this.handleSubmit}>
          <Tab key="account" tab="账户密码登录">
            <UserName name="username" placeholder="请输入帐号..." />
            <Password name="password" placeholder="请输入密码..." />
          </Tab>
{/*           <div>
            <Checkbox checked={this.state.autoLogin} onChange={this.changeAutoLogin}>
              自动登录
            </Checkbox>
          </div> */}
          <Submit loading={submitting}>登录</Submit>
        </Login>
      </div>
    );
  }
}

src/models/login.js 全部代码 

import { routerRedux } from 'dva/router';
import { linkApi } from '../services/api';
import { setAuthority } from '../utils/authority';
import { reloadAuthorized } from '../utils/Authorized';

import { notification } from 'antd';


export default {
  namespace: 'login',

  state: {
    status: undefined,
  },

  effects: {
    *login({ payload }, { call, put }) {
      const response = yield call(linkApi, {
        cmd:"tx.web.restful.apis.controllers.services.base.BaseService#login",
        datas:{
          username:payload.username,
          password:payload.password,
          eType:0
        },
      });
      // Login successfully
      if (response.state == 200 ) {
        yield put({
          type: 'changeLoginStatus',
          payload: response.datas
        });
        reloadAuthorized();
        yield put(routerRedux.push('/'));
      }
    },
    *logout(_, { put, select }) {
      try {
        // get location pathname
        const urlParams = new URL(window.location.href);
        const pathname = yield select(state => state.routing.location.pathname);
        // add the parameters in the url
        urlParams.searchParams.set('redirect', pathname);
        window.history.replaceState(null, 'login', urlParams.href);
      } finally {
        yield put({
          type: 'changeLoginStatus',
          payload: ""
        });
        reloadAuthorized();
        yield put(routerRedux.push('/user/login'));
      }
    },
  },

  reducers: {
    changeLoginStatus(state, { payload }) {
      setAuthority(payload);
      return {
        ...state,
        status: payload.status,
        type: payload.type,
      };
    },
  },
};

回答一:

({login, loading})=>({}) 这是一个函数,和connect 函数的两个参数不同,我应该如何理解这个写法?

这是使用的第一个函数mapStateToProps(state, ownProps) ps: 两个参数相对应。
   login:这个参数就是[models/login.js]里面,[reducers/changeLoginStatus]的返回值。
   

login和submitting这个怎么理解,是指绑定到submitting到组件的this.props里面吗?

按资料说法,这两个都是要加到this.props上面的对象。 

那么他是如何把src/models/login.js 里面的effects触发的?

[models/login.js],应该在声明路由[common/router.js]的时候就已经指定,
   触发应该是用的[ruotes/User/Login.js]的[handleSubmit]

 

并且在组件中没有看到如何方法调用submitting.

调用应该是指这里[ruotes/User/Login.js]的[render]

 

loading.effects['login/login'] 这个方法应该如何理解?

这个就是猜测了,应该是返回的[model/login.js]下面[*login]的执行状态,bool值。

回答二:

说一下我当时遇到这个写法的的疑惑,是我太菜,没看懂是箭头函数,总以为该箭头函数必须要这样写,()=>{ ...函数体代码} ,查了一下,如果箭头函数直接返回一个对象,必须在对象外面加上括号。这里是直接返回了一个对象的写法,()=>({}) 等价于 ()=>{return {}}。希望对箭头函数有疏漏的童鞋留意一下。

回答三:

({login, loading})=>({}) 这是一个函数,和connect 函数的两个参数不同,我应该如何理解这个写法?

{login,loading} --> 这个是赋值解构的写法.mapStateToProps的第一个参数为state.
这个写法是等同于

login=state.login
loading=state.loading

里面的函数可以直接用login和loading.

不知对错,不过理解起来是对的.
按前面 messycodecc的说法的话,下面的代码就无法解释了,里面竟然有这么duo

pages/Dashboard/Workplace.js:@connect(({ user, project, activities, chart, loading }) => ({

猜你喜欢

转载自blog.csdn.net/falcon95/article/details/85140465
今日推荐