有没有办法避免 React + Redux 中的可选属性?
Is there a way to avoid optional properties in React + Redux?
有没有办法避免在 react in combination with redux 中有可选的 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;
我的组件 redux:
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 />
的道具。事情是,我知道这些道具将被提供,因为我通过 redux.
明确分配它们
将它们保留为可选参数是可行的,但问题是,在使用它们时我必须做进一步不必要的检查。
例如。
const { quizEditor } = props;
return (
{quizEditor.map( //... ) }
)
错误,因为 quizEditor
可能 undefined
作为可选道具,所以我必须做
{ quizEditor && quizEditor.map( //... ) }
现在从技术上讲,这只是一个小烦恼,但仍然是一个烦恼,感觉应该有一些我想念的方法可以让你两全其美。
{ connect }
函数需要提供一个 strong-typed 参数。否则它假定提供的参数是组件本身的道具,而不仅仅是 redux
道具。
两个例子假设相同header:
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);
在省略自己的 Props 的情况下,您只需传递一个空的 object { }
来代替它。
type Props = StateProps & DispatchProps
// ...
connect<StateProps, DispatchProps, {}>(// ...)
有没有办法避免在 react in combination with redux 中有可选的 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;
我的组件 redux:
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 />
的道具。事情是,我知道这些道具将被提供,因为我通过 redux.
将它们保留为可选参数是可行的,但问题是,在使用它们时我必须做进一步不必要的检查。
例如。
const { quizEditor } = props;
return (
{quizEditor.map( //... ) }
)
错误,因为 quizEditor
可能 undefined
作为可选道具,所以我必须做
{ quizEditor && quizEditor.map( //... ) }
现在从技术上讲,这只是一个小烦恼,但仍然是一个烦恼,感觉应该有一些我想念的方法可以让你两全其美。
{ connect }
函数需要提供一个 strong-typed 参数。否则它假定提供的参数是组件本身的道具,而不仅仅是 redux
道具。
两个例子假设相同header:
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);
在省略自己的 Props 的情况下,您只需传递一个空的 object { }
来代替它。
type Props = StateProps & DispatchProps
// ...
connect<StateProps, DispatchProps, {}>(// ...)