我找到了一种使用mapStateToProps
中的react-redux
时获得类型安全性的方法:作为the documentation,您可以定义一个接口并使用该接口参数化React.Component<T>
。
但是,当我定义mapStateToProps
时,我已经在定义一个函数,可以在该函数中推断结果对象的属性类型。例如,
function mapStateToProps(state: MyState) {
return {
counter: state.counter
};
}
在这里,可以推断道具counter
与state.counter
的类型相同。但是我仍然必须具有如下的样板代码:
interface AppProps {
counter: number;
}
class App extends React.Component<AppProps> { ... }
export default connect(mapStateToProps)(App);
所以问题是,有什么方法可以构造代码,以便避免两次编写counter
类型的代码?或者,为了避免参数化React.Component
的类型,即使我可以从mapStateToProps
函数的显式结果类型中推断出组件的属性,那还是更好的选择。我想知道上面的复制是否确实是使用React-Redux编写类型化组件的正常方法。
答案 0 :(得分:3)
我不这么认为。您可以使用Redux钩子来简化设置:https://react-redux.js.org/next/api/hooks
// Your function component . You don't need to connect it
const App: React.FC = () => {
const counter = useSelector<number>((state: MyState) => state.counter);
const dispatch = useDispatch(); // for dispatching actions
};
编辑:如果您只使用相同的MyState
类型,则可以。但是我不认为你会那样想要。
答案 1 :(得分:3)
是的。有一种精巧的技术可以根据 shell: /bin/bash -e {0}
npm WARN Gatsby_site No repository field.
npm WARN Gatsby_site No license field.
added 33 packages from 26 contributors and audited 43 packages in 0.952s
found 0 vulnerabilities
> @ test /home/runner/work/Gatsby_site/Gatsby_site
> bash mdlint.sh
fatal: ambiguous argument 'master': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
和connect
来推断mapState
将传递给组件的组合道具的类型。
mapDispatch
中有一个新的ConnectedProps<T>
类型。您可以像这样使用它:
@types/react-redux@7.1.2
请注意,如果function mapStateToProps(state: MyState) {
return {
counter: state.counter
};
}
const mapDispatch = {increment};
// Do the first half of the `connect()` call separately,
// before declaring the component
const connector = connect(mapState, mapDispatch);
// Extract "the type of the props passed down by connect"
type PropsFromRedux = ConnectedProps<typeof connector>
// should be: {counter: number, increment: () => {type: "INCREMENT"}}, etc
// define combined props
type MyComponentProps = PropsFromRedux & PropsFromParent;
// Declare the component with the right props type
class MyComponent extends React.Component<MyComponentProps> {}
// Finish the connect call
export default connector(MyComponent)
是对象,则可以正确推断出mapDispatch
中包含的重击动作创建者的类型,而typeof mapDispatch
则不是。
作为推荐的方法,我们很快会将其添加到React-Redux官方文档中。
更多详细信息:
答案 2 :(得分:2)
我将分别键入映射的调度道具和组件道具,然后将映射状态的推断类型组合到道具功能。请参见下面的快速示例。也许会有更优雅的解决方案,但希望它能使您走上正确的轨道。
import * as React from "react";
import { Action } from "redux";
import { connect } from "react-redux";
// Lives in some lib file
type AppState = {
counter: number;
};
type MappedState = {
computedValue: number;
};
type MappedDispatch = {
doSomethingCool: () => Action;
};
type ComponentProps = {
someProp: string;
};
const mapStateToProps = (state: AppState) => ({
computedValue: state.counter
});
const mapDispatchToProps: MappedDispatch = {
doSomethingCool: () => {
return {
type: "DO_SOMETHING_COOL"
};
}
};
type Props = ReturnType<typeof mapStateToProps> &
MappedDispatch &
ComponentProps;
class DumbComponent extends React.Component<Props> {
render() {
return (
<div>
<h1>{this.props.someProp}</h1>
<div>{this.props.computedValue}</div>
<button onClick={() => this.props.doSomethingCool()}>Click me</button>
</div>
);
}
}
const SmartComponent = connect(
mapStateToProps,
mapDispatchToProps
)(DumbComponent);
export default SmartComponent;