Fel*_*iel 8 javascript typescript reactjs redux react-redux
我正在使用redux和typescript作为我当前的webapp.
定义组件的道具的最佳实践是什么,该组件通过@connect父级接收redux-actions ,但也来自父级?例:
// mychild.tsx
export namespace MyChildComponent {
export interface IProps {
propertyFromParent: string;
propertyFromRedux: string; // !!!! -> This is the problem
actionsPropertyFromRedux: typeof MyReduxActions; // !!!! -> And this
}
}
@connect(mapStateToProps, mapDispatchToProps)
export class MyChildComponent extends React.Component <MyChildComponent.IProps, any> {
... react stuff
}
function mapStateToProps(state: RootState) {
return {
propertyFromRedux: state.propertyFromRedux
};
}
function mapDispatchToProps(dispatch) {
return {
actionsPropertyFromRedux: bindActionCreators(MyReduxActions as any, dispatch)
};
}
// myparent.tsx
export class MyParentComponent extends React.Component <MyParentComponent.IProps, any> {
... react stuff
render(){
// typescript complains, because I am not passing `propertyFromRedux`!
return <div><MyChildComponent propertyFromParent="yay" /></div>;
}
}
Run Code Online (Sandbox Code Playgroud)
我看到它有两个解决方案.
只需通过我的整个应用程序传递操作和状态.但这意味着即使只是一些小的子组件必须改变,我的整个应用程序也会被重新渲染.或者是在所有商店更改中收听我的顶级组件的redux方式?然后我必须在内部编写很多逻辑shouldComponentUpdate来制作没有扁平物体的道具.
设置帕拉姆中IProps的MyChildComponent 这样的可选:
-
// mychild.tsx
export namespace MyChildComponent {
export interface IProps {
propertyFromParent: string;
propertyFromRedux?: typeof MyAction; // This is the problem
}
}
Run Code Online (Sandbox Code Playgroud)
还有另外一种方法吗?上述两种方式在我眼中看起来都太乱了.
Tyl*_*ian 19
您需要拆分你的道具-你需要一个DispatchProps,StateProps和OwnProps类型.你还必须使用TypeScript的泛型connect
DispatchProps 是你的行动创造者.StateProps是你的状态道具(duh) - 这些来自mapStateToProps- 该函数的返回类型应该匹配此类型.OwnProps是你的组件接受(也许是预期)的道具.可选的道具应在界面中标记为可选.我这样做的方式(没有装饰器,但我相信它适用于此)是
interface ComponentDispatchProps {
doSomeAction: typeof someAction;
}
interface ComponentStateProps {
somethingFromState: any;
}
interface ComponentOwnProps {
somethingWhichIsRequiredInProps: any;
somethingWhichIsNotRequiredInProps?: any;
}
// not necessary to combine them into another type, but it cleans up the next line
type ComponentProps = ComponentStateProps & ComponentDispatchProps & ComponentOwnProps;
class Component extends React.Component<ComponentProps, {}> {...}
function mapStateToProps(state, props) {
return { somethingFromState };
}
export default connect<ComponentStateProps, ComponentDispatchProps, ComponentOwnProps>(
mapStateToProps,
mapDispatchToProps
)(Component);
Run Code Online (Sandbox Code Playgroud)
我认为你必须使用@connect<StateProps, DispatchProps, OwnProps>哪个将装饰并返回一个接受的类OwnProps.
如果你看一下connectTS 中的s实现
export declare function connect<TStateProps, TDispatchProps, TOwnProps>(...): ComponentDecorator<TStateProps & TDispatchProps, TOwnProps>
interface ComponentDecorator<TOriginalProps, TOwnProps> {
(component: ComponentClass<TOriginalProps> | StatelessComponent<TOriginalProps>): ComponentClass<TOwnProps>;
}
Run Code Online (Sandbox Code Playgroud)
connect<...>返回一个ComponentDecorator,当传递组件时(在你的情况下,这是在转发装饰器时透明地完成),无论如何StateProps,并DispatchProps返回一个期望的组件OwnProps.
connect (非泛型)返回 InferableComponentDecorator
export interface InferableComponentDecorator {
<P, TComponentConstruct extends (ComponentClass<P> | StatelessComponent<P>)>(component: TComponentConstruct): TComponentConstruct;
}
Run Code Online (Sandbox Code Playgroud)
它试图根据提供给组件的道具来推断道具,在你的情况下是所有道具的组合(从上面OwnProps变成ComponentProps).
| 归档时间: |
|
| 查看次数: |
2553 次 |
| 最近记录: |