如何在没有构造函数的情况下使用 Typescript 在 React 中正确设置初始状态?



在现代JS中,我们可以直接为React组件设置初始状态,如下所示:

class App extends React.Component {
state = {value: 10}
render() {
return <div>{this.state.value}</div>
}
}

当我尝试使用Typescript执行此操作时,TSLint说"类属性'状态'必须标记为'私有','公共'或'受保护'"。如果我将其设置为"私有",则 linter 将在App上报告Class 'App' incorrectly extends base class 'Component<{}, { value: number; }, any>'. Property 'state' is private in type 'App' but not in type 'Component<{}, { value: number; }, any>'.。我知道我可以调整 linter 规则以跳过此类检查,但一般来说,检查类属性的可见性是我想利用的一件好事。

在测试了所有三个选项之后,仅选择"公共"不会得到 TSLint 抛出错误。但是由于这里的状态表示这个特定组件的内部状态,因此将其设置为公共似乎很奇怪。我这样做的方式是否正确?

class App extends React.Component<{}, { value: number }> {
public state = { value: 10 };
public render() {
return <div>{this.state.value}</div>;
}
}

在我在网上找到的所有 TS-React 教程中,都使用了构造函数,就像在旧的 JS 语法中一样。

class App extends React.Component<{}, { value: number }> {
constructor(props: any) {
super(props);
this.state = { value: 10 };
}
public render() {
return <div>{this.state.value}</div>;
}
}

在 Typescript 中直接设置类属性是否被视为不良做法/风格?

我的做法是否正确?

是的。

在 Typescript 中直接设置类属性是否被视为不良样式?

不。

稍微好一点的方法

请考虑将状态声明为public readonly,并使用只读修饰符。

这将满足 TSLint 的要求,同时也为您提供一些保护,防止被错误修改(即不使用this.setState(。 即使状态仍然暴露在外部,这通常也不是问题。

interface IState {
value: number;
}
class App extends React.Component<{}, IState> {
public readonly state: Readonly<IState> = {
value: 10
}
public render() {
return <div>{this.state.value}</div>
}
}

TSLint 规则

显式声明访问修饰符是一件好事,即使它隐式导致相同的访问。它有助于保持代码清晰,所以我不会禁用此 TSLint 规则。

我会说直接设置 React 组件的state属性是一种不好的做法,除非您将类型注释为与状态类型参数相同以React.Component。 如果没有注释,TypeScript 会根据初始值设定项确定this.state的类型,覆盖超类(基于状态类型参数(的类型,并且如果初始值设定项中的类型显示为类型参数的子类型,则不会给出错误。 这可能会导致以后出现不健全或意外行为;有关示例,请参阅此线程。

状态是不可变的。设置初始状态的推荐方法是通过构造函数。

请注意,"state"已经定义并继承,因此无需重新声明它:

interface AppState {
charge : number;
spin   : number;
color  : string;
}
interface AppProps {}
class App extends React.Component<AppProps, AppState> {
constructor(props) {
super(props);
this.state={ charge: 0, spin: -0.5, color:'red' }; 
}
}

顺便说一句,这正是它在反应文档中的定义:

class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
...

相关内容

  • 没有找到相关文章

最新更新