cor*_*vid 12 javascript typescript reactjs
我有一个"更高阶的组件",它以下面的方式实现(没有类型).
const Themeable = (mapThemeToProps) => {
return (WrappedComponent) => {
const themedComponent = (props, { theme: appTheme }) => {
return <WrappedComponent
{...props}
theme={merge(
{},
defaultTheme,
appTheme,
mapThemeToProps(merge(defaultTheme, appTheme))
)}
>
}
themedComponent.contextTypes = { theme: PropTypes.object };
return themedComponent;
}
}
Run Code Online (Sandbox Code Playgroud)
总结它的作用,它需要一个mapThemeToProps功能.这将接收通过合并defaultTheme(由我的库appTheme提供)和(由ThemeProvider组件通过上下文提供)创建的主题参数.然后它将创建一个扩展Theme并将其作为被调用的prop传递给组件theme.在实践中,它将按如下方式使用(Themeable在此范围内调用):
const mapThemeToProps = (theme) => ({
background: theme.palette.dark,
color: theme.text.light,
});
function Greeting({ theme: { background, color } }) {
return (
<div style={{ background, color }}>
Hello World!
<div>
)
}
export default Themeable(mapThemeToProps)(Greeting);
Run Code Online (Sandbox Code Playgroud)
我很难为这个功能开发一个正确的输入.我发现这种模式非常类似于某些东西connect,react-redux因此从他们的打字作为我的起点.无论如何,我有点失落,这基本上是我所在的地方:
import { Theme } from 'types/Theme';
interface ThemeableComponentEnhancer {
<P>(component: React.ComponentType<P>): React.ComponentClass<Pick<P, "theme"> & { theme: Theme }> & { WrappedComponent: React.Component<P>}
}
export interface Themeable {
// calling it with no parameters returns a basic theme.
(): Theme;
// calling it with a function
<TTheme = {}>(mapThemeToProps: MapThemeToPropsParam<TTheme>): ComponentEnhancer<{ theme: TTheme }>;
}
interface MapThemeToProps<TTheme> {
(theme: TTheme): TTheme;
}
interface MapThemeToPropsFactory<TTheme> {
(theme: Theme): MapThemeToProps<TTheme>;
}
type MapThemeToPropsParam<TTheme> = MapStateToPropsFactory<TTheme>
Run Code Online (Sandbox Code Playgroud)
我无法理解这个问题.如何在TypeScript中完成?
Theme.tsexport interface Theme {
palette: {
primary: string;
secondary: string;
};
}
export const theme: Theme = {
palette: {
primary: 'red',
secondary: 'yellow'
}
};
Run Code Online (Sandbox Code Playgroud)
Rect组件Themeimport * as React from 'react';
import { Theme } from '../theme/Theme';
import withTheme, { MapThemeToProps } from '../theme/withTheme';
export interface RectThemeProps {
titleColor?: string;
bodyColor?: string;
}
export interface RectProps extends RectThemeProps {
content?: string;
}
export class Rect extends React.Component<RectProps> {
render() {
const {titleColor, bodyColor, content} = this.props;
return <div>{content && content}</div>;
}
}
const mapThemeToProps: MapThemeToProps<
RectThemeProps,
Theme
> = (theme) => {
return {
titleColor: theme.palette.primary,
bodyColor: theme.palette.secondary
};
};
export default withTheme(mapThemeToProps)(Rect);
Run Code Online (Sandbox Code Playgroud)
withTheme.tsimport * as React from 'react';
const ID = '__context_id__';
export interface MapThemeToProps<M, T> {
(theme: T): M;
}
export interface withTheme {
<M, T>(mapThemeToProps: MapThemeToProps<M, T>):
(c: React.ComponentType<M>) => React.ComponentType<M>;
}
export default <M, T>(
mapThemeToProps: MapThemeToProps<M, T>
) => (Component: React.ComponentType<M>) => {
return class extends React.Component<M> {
render() {
const theme = this.context[ID];
return (
<Component
{...this.props}
{...mapThemeToProps(theme.getTheme())}
/>
);
}
};
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
325 次 |
| 最近记录: |