gpt4 book ai didi

reactjs - react / typescript : Consuming context via HOC

转载 作者:搜寻专家 更新时间:2023-10-30 20:36:54 25 4
gpt4 key购买 nike

我正在尝试实现示例 Consuming Context with a HOC来自 TypeScript (2.8) 中的 React 文档 (React 16.3),但惨遭失败。作为引用,React 手册中的代码:

const ThemeContext = React.createContext('light');

// This function takes a component...
export function withTheme(Component) {
// ...and returns another component...
return function ThemedComponent(props) {
// ... and renders the wrapped component with the context theme!
// Notice that we pass through any additional props as well
return (
<ThemeContext.Consumer>
{theme => <Component {...props} theme={theme} />}
</ThemeContext.Consumer>
);
};
}

我能想到的最好的:

export interface ThemeAwareProps {
theme: string;
}

const ThemeContext = React.createContext('light');

export function withTheme<P extends ThemeAwareProps, S>(Component: new() => React.Component<P, S>) {
return function ThemedComponent(props: P) {
return (
<ThemeContext.Consumer>
{theme => <Component {...props} theme={theme} />}
</ThemeContext.Consumer>
);
};
}

class App extends React.Component {

public render() {
return (
<ThemeContext.Provider value={'dark'}>
<ThemedButton/>
</ThemeContext.Provider>
);
}
}

ThemedButton.tsx:

interface ThemedButtonProps extends ThemeAwareProps {
}

interface ThemedButtonState{
}

class ThemedButton extends React.Component<ThemedButtonProps, ThemedButtonState> {

constructor(props: ThemedButtonProps) {
super(props);
}


public render() {
return (
<button className={this.props.theme}/>
)
}
}

export default withTheme(ThemedButton);

问题出在最后一行 ( export default withTheme(ThemedButton) )。 TypeScript 编译器提示说

Argument of type typeof ThemedButton is not assignable to parameter of type new () => Component<ThemedButtonProps, ThemedButtonState, any>.

我错过了什么?

最佳答案

你大部分都做对了,只是少了一些:

  1. Component , 使用 React.ComponentType<Props> ,它正确地接受类组件和功能组件。我想使用 new () => ...单独在这里不起作用,因为签名不完全匹配。

  2. ThemedButton 中排除 Prop 在使用它时,您必须使用一些看起来很神奇的语法:

function ThemedComponent(props: Pick<P, Exclude<keyof P, keyof ThemeAwareProps>>)

这是它的作用:

  • Exclude<keyof P, keyof ThemeAwareProps>表示“获取 P 的 key ,然后拿走 ThemeAwareProps 中的 key ”
  • Pick<P, ...>然后说,“从 P 返回一个只有这些属性的对象类型”

结合这些给我们一个组件,它接受 ThemedButton 的所有 Prop 确实,减去 theme Prop ,这样我们就可以做<ThemedButton />没有错误。

这是完整的 HOC:

function withTheme<P extends ThemeAwareProps>(Component: React.ComponentType<P>) {
return function ThemedComponent(props: Pick<P, Exclude<keyof P, keyof ThemeAwareProps>>) {
return (
<ThemeContext.Consumer>
{(theme) => <Component {...props} theme={theme} />}
</ThemeContext.Consumer>
)
}
}

And finally, a good blog post on the subject, from which I gleamed most of this information from.它还包括一种缩短 Pick<...> 的方法带有 Omit 的东西如果您愿意,请键入。


编辑:The behavior of rest/spread has changed in 3.2 , 和 this bug came up as an unfortunate side effect ,导致 props 的类型与其他 Prop 合并时被删除。 A currently working workaround is to cast props as P :

    return (
<ThemeContext.Consumer>
{(theme) => <Component {...props as P} theme={theme} />}
</ThemeContext.Consumer>
)

关于reactjs - react / typescript : Consuming context via HOC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50612299/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com