我正在尝试从基于类的组件迁移到功能组件。它是使用mapState
连接的组件。
这就是我所拥有的:
import { connect } from 'react-redux'
import { fetchArticles } from '../shared/actions/articleActions';
import { AppState } from '../shared/types/genericTypes';
import Article from '../shared/models/Article.model';
type Props = {
articles?: Article[]
fetchArticles?: any,
};
const mapState = (state: AppState, props) => ({
articles: state.articleReducers.articles,
...props
});
const actionCreators = {
fetchArticles,
};
class NewsArticles extends Component<Props> {
componentDidMount() {
if (!this.props.articles || !this.props.articles.length) {
this.props.fetchArticles();
}
}
render() {
return (...);
}
}
export default connect(mapState, actionCreators)(NewsArticles)
这是我现在拥有的:
// same imports except for FC and useEffec from react.
type Props = {
articles?: Article[];
fetchArticles?: any;
};
const mapState = (state: AppState, props: Props) => ({
articles: state.articleReducers.articles,
...props,
});
const actionCreators = {
fetchArticles,
};
const NewsArticles: FC<Props> = ({ articles, fetchArticles }) => {
useEffect(() => {
if (!articles || !articles.length) {
fetchArticles();
}
}, []);
return (...);
};
export default connect(mapState, actionCreators)(NewsArticles);
我主要关心的是道具。
在他们像这样之前
const mapState = (state: AppState, props) => ({
articles: state.articleReducers.articles,
...props
});
并以此方式使用:
componentDidMount() {
if (!this.props.articles || !this.props.articles.length) {
this.props.fetchArticles();
}
}
现在我有了一个功能组件,我正在得到这个
const mapState = (state: AppState, props: Props) => ({
articles: state.articleReducers.articles,
...props,
});
并以此方式使用:
useEffect(() => {
if (!articles || !articles.length) {
fetchArticles();
}
}, []);
既然props
和articles
的调用方式不像fetchArticles
,只有this.props.articles
这样,articles
的工作原理确实有意义…props
上的mapState
?
答案 0 :(得分:0)
无需在mapState
中传播道具。
此:
const mapState = (state: AppState, props: Props) => ({
articles: state.articleReducers.articles,
...props,
});
等效于此:
const mapState = (state: AppState) => ({
articles: state.articleReducers.articles,
});
除了mapState
和mapDispatch
(您称为actionCreators
)中的道具之外,任何额外的道具都将传递到您的组件中。
答案 1 :(得分:0)
您的代码是可编译的,但使用connect
函数签名不能完全正确。让我们来看看签名
<TStateProps = {}, TDispatchProps = {}, TOwnProps = {}, State = {}>(
mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,
mapDispatchToProps: MapDispatchToPropsNonObject<TDispatchProps, TOwnProps>
): InferableComponentEnhancerWithProps<TStateProps & TDispatchProps, TOwnProps>;
它有4种类型,
TSTateProps
是道具类型,源自Redux状态。在您的示例中,它们是
type StateProps = {
articles: Article[];
}
仅articles
源自Redux状态。
TDispatchProps
是包含您的组件将分派的动作的道具类型。当您将actionCreators
对象传递给connect
TDispatchProps
时,应该等于typeof actionCreators
(我们应该得到对象actionCreators
的类型)。
TOwnProps
是组件从父级(而不是Redux)获得的道具类型。您不使用父级的道具,因此TOwnProps
等于{}
。
TState
是Redux中的状态类型。是AppState
。
要完全正确使用Redux,您应该
type StateProps = {
articles: Article[];
};
const mapState = (state: AppState): StateProps => ({
articles: state.articleReducers.articles
});
const actionCreators = {
fetchArticles,
};
type Props = StateProps & typeof actionCreators; // These is correct props for your component
const NewsArticles: FC<Props> = ({ articles, fetchArticles }) => {
如果以后要添加来自父级的道具,只需将它们与Props
相交即可。
type Props = StateProps & typeof actionCreators & OwnProps;
将...props
添加到mapState
时,您的代码可以正常工作。并且props
包含成员fetchAction
。因此,您终于得到了与我在答案中显示的相同的Props
,但略有错误。