ReactJS和Redux-正确创建具有类型的连接类组件

时间:2019-10-30 13:32:45

标签: javascript reactjs redux react-redux

所以我开始学习React + Redux。

我得到了以下减速器:

/**
 * Import custom types.
 */
import { User } from "../types/user.type";
import { Action } from "../types/reducers/profileReducer.type";

/**
 * Creates profile reducer to set and retrieve currently logged in user.
 * @param user - User object, indicating the current state.
 * @param action - Action object, which will indicate which action to apply.
 * @returns User object after the action applied.
 */
const profileReducer = (user: User | null = null, action: Action) => {
  switch(action.type) {
    case 'SET_PROFILE': // Set users profile
      return user = action.payload ? action.payload.user : null;
    default: // Let's set the default action to retrieve the users profile
      return user;
  }
};

/**
 * Export default reducer.
 */
export default profileReducer;

然后采取行动-

/**
 * Import custom types.
 */
import { User } from '../types/user.type';
import { Action } from '../types/reducers/profileReducer.type';

/**
 * Returns an action for setting a profile.
 * @param user - User object which should be set as current users profile.
 * @returns Action for setting a new users profile object.
 */
export const setProfile = (user: User): Action => {
  return {
    type: 'SET_PROFILE',
    payload: {
      user 
    }
  };
}

/**
 * Export all profile actions.
 */
export default {
  setProfile
}

最后是这些类型-

profileReducer:

/**
 * Import custom types.
 */
import { User } from "../user.type";

export interface Action {
  type: ActionType; // Type of the action
  payload?: {
    user: User; // User object which will be set upon 'SET_PROFILE' action
  }
};

export type ActionType = 'SET_PROFILE';

用户:

export interface User {
  id: string; // ID of the user
  name: string; // Name of the user
  lastName: string; // Last name of the user
  email: string; // Email of the user
  admin: boolean; // Boolean indicator if the user is admin
  active: boolean; // Boolean indicator if the user is active
  gender: boolean; // Gender of the user
  createdAt: string; // Date object when the user was created
  updatedAt: string; // Date object when the user was updated
  birthDate: number; // Date when user was born
  birthYear: number; // Year when user was born
  birthMonth: number; // Month when user was born
}

现在我有以下课程组件-

/**
 * Import React libraries.
 */
import React, { Dispatch } from 'react';
import { Link, Redirect } from 'react-router-dom';

/**
 * Import third-party libraries.
 */
import Navbar from 'react-bootstrap/Navbar';
import Col from 'react-bootstrap/Col';
import Row from 'react-bootstrap/Row';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { connect } from 'react-redux';

/**
 * Import custom reducer actions.
 */
import actions from '../../actions';

/**
 * Import custom types.
 */
import { HeaderProps } from '../../types/header.type';
import { User } from '../../types/user.type';
import { Action } from '../../types/reducers/profileReducer.type';

/**
 * Import custom scss.
 */
import './Header.scss';

/**
 * Creates Header component class.
 */
class HeaderComponent extends React.Component<HeaderProps> {
  /**
   * Renders Header component view.
   */
  render() {
    return (
      <Row>
        <Col md="12">
          { !this.state.isLoggedIn && <Redirect to="/" /> }
          <Navbar bg="light" expand="lg" className="app-header">

          { /* Style for medium and larger devices */ }
          <div className="d-none d-md-block text-right w-100">
            <Link to="/profile" className="text-dark">
              <FontAwesomeIcon icon="user" className="mr-2" />
              { this.props.profile && `${this.props.profile.name} ${this.props.profile.lastName}` }
            </Link>
          </div>
          </Navbar>
        </Col>
      </Row>
    )
  }
}

/**
 * Creates profile state and sets as parameters for the header component.
 * @param state - Redux store state object.
 */
const mapStateToProps = (state: any) => ({ profile: state.profile });

/**
 * Creates a dispatch mapping, which will be passed in to properties.
 * @param dispatch - Dispatch parameter which takes in a specific action.
 */
const mapDispatchToProps = (dispatch: Dispatch<Action>) => ({
  setProfile: (user: User) => dispatch(actions.profile.setProfile(user))
});

/**
 * Export default header component.
 */
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(HeaderComponent);

HeaderProps如下:

export interface HeaderProps {
  profile?: User; // Currently logged in users profile
  setProfile?: Function; // Dispatch function on redux.
}

当前出现几个问题:

1)如果我从HeaderProps属性中删除了可选符号(?),则reactJs应用程序将不再编译,并抱怨在调用Header组件的父组件中缺少属性。这是由于以下事实:我在调用<Header />时没有传递任何属性,也就是说,我只是调用<Header />而不是<Header setProfile={..} profile={} />,因为显然-我们正在检索它们从连接功能,对不对?该如何解决?

2)我应该为状态使用什么类型?我目前在哪里state: any?我似乎无法弄清楚。

3)我是否已正确使用mapDispatchToProps函数的类型?如果没有,您将如何更改?

4)我是否正确定义了组件的类型?我无法访问默认的反应功能,例如setState,e.t.c.我应该自己在HeaderProps类型中定义它们吗?

5)您在使用redux的方式上是否看到任何问题?在本教程中,他们将它们分为两个单独的文件-一个保存Header实现,另一个保存与Header的redux连接。我这样做的方式还可以吗?

0 个答案:

没有答案