有没有办法避免React + Redux中的可选属性?

时间:2019-12-25 11:47:52

标签: reactjs typescript redux react-redux react-props

是否有办法避免将中的可选props结合使用?

假设我具有以下结构:

调用该组件的HOC:

import React from 'react';
import QuizEditor from './QuizEditor';

const Quiz: React.FC = () => (
 <div>
   // <QuizMenu /> not necessary for this example
   <QuizEditor />
 </div>
)

export default Quiz;

我的组件:

import React from 'react';
import { connect } from 'react-redux';
import { StoreState, QuizType } from 'quiz/types';
import { actionAddQuiz } from 'quiz/actions';

type Props = {
  quizEditor: QuizType;
  actionAddQuiz: () => object;
}

const QuizEditor: React.FC<Props> = (props:Props) => (
  // further code here...
)

const mapStateToProps = (state: StoreState): object => ({
  quizEditor: state.quizEditor,
})

const mapDispatchToProps = { actionAddQuiz };

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(QuizEditor);

现在,这显然是错误的,因为缺少提供给<QuizEditor />的道具。事实是,我知道会提供这些道具,因为我是通过明确分配它们的。

将它们保留为可选参数是可行的,但是问题是,当我使用它们时,我必须做进一步的不必要的检查。

例如

const { quizEditor } = props;
return (
  {quizEditor.map( //... ) }
)

错误,因为quizEditor可能是undefined作为可选道具,所以我不得不这样做

{ quizEditor && quizEditor.map( //... ) }

现在从技术上讲,这只是个小麻烦,但仍然令人烦恼,并且感觉应该在某种程度上我想念的东西可以让您同时拥有两全其美的感觉。

是否可以将组合在一起而不必使用可选的props

1 个答案:

答案 0 :(得分:0)

{ connect }函数需要提供一个强类型的参数。否则,假定提供的参数是Component本身的道具,而不仅仅是redux道具。

两个示例都假定使用相同的标题:

import React from 'react';
import { connect } from 'react-redux';
import { someAction  } from '../actions';

这是一个解决所有问题的组件的示例。

// could type it explicitly, but this would take forever with every action
type StateType = { //... }
type DispatchProps = typeof someAction;
type StateProps = { someStateProp1: boolean; someStateProp2: number; };
type OwnProps = { disabled: boolean; };

type Props = StateProps & DispatchProps & OwnProps

const Example: React.FC<Props> = (props: Props) => (
   <button disabled={props.disabled} crazyCustomProp={props.someStateProp1} />
);

const mapStateToProps = (state: StateType): StateProps => ({
   someStateProp1: state.someStateProp1,
   someStateProp2: state.someStateProp2,
});

const mapDispatchToProps = {
  someAction,
};

export default connect<StateProps, DispatchProps, OwnProps>(
    mapStateToProps,
    mapDispatchToProps,
)(Example);

如果省略了自己的道具,您只需在其位置传递一个空对象{ }

type Props = StateProps & DispatchProps
// ...
connect<StateProps, DispatchProps, {}>(// ...)