如何在 React 中使用 Flow 类型?
How to use Flow types with React?
假设我有一个 App
组件,其状态由一个对象组成,该对象的形状由以下流类型给出:
type Person = {
fname: string,
lname: string
};
为了断言我的组件的状态确实是 Person
类型,我在 getInitialState
中创建了一个人工局部变量,以便我可以注释类型:
const App = React.createClass({
getInitialState: function() {
const person : Person = {fname: 'John', lname: 'Doe'};
return {person: person};
}
, render: function() {
return (
<PersonDetails person={this.state.person}/>
);
}
});
以上工作(尽管必须声明 const person
是一个小的不便)。
当我希望将该状态作为另一个组件的 属性 传递时,问题就出现了。在那种情况下,我没有找到其他解决方案,只能使用 React 的 PropTypes
API:
重新定义 Person 的形状
const PersonDetails = React.createClass({
propTypes: {
person: React.PropTypes.shape({fname: React.PropTypes.string.isRequired,
lname: React.PropTypes.string.isRequired}).isRequired
},
render: function() {
return (
<div>
<span>{this.props.person.fname}</span>
<span>{this.props.person.lname}</span>
</div>
);
}
});
这显然不是 DRY,而且我使用两种不同的方法来提供静态类型信息(Flow 和 React.PropTypes API)。
有没有办法让PersonDetails
组件重用Person
的类型声明?
我发现的唯一方法是使用正确的 类(不是 React 类型):
class Person {
fname: string;
lname: string;
constructor(fname: string, lname: string) {
this.fname = fname;
this.lname = lname;
}
};
const PersonDetails = React.createClass({
propTypes: {
person: React.PropTypes.instanceOf(Person).isRequired
},
render: function() {
return (
<div>
<span>{this.props.person.fname}</span>
<span>{this.props.person.lname}</span>
</div>
);
}
});
const App = React.createClass({
getInitialState: function() {
const person : Person = new Person('John', 'Doe');
return {person: person};
}
, render: function() {
return (
<PersonDetails person={this.state.person}/>
);
}
});
export default App;
… 虽然上面成功地重用了定义,但我不清楚何时应该使用 Flow 类型而不是 类 来静态类型检查我的组件。另外,我不确定这两种方法是否真的等同(例如,在能够表达值的可空性方面)。
声明你的类型一次并导出它:
// types/index.js
export type Person = {|
fname: string,
lname: string,
|}
然后到处重复使用它。
在组件的state
中:
// App.js
import type { Person } from './types'
type State = {|
person: Person,
|}
class App extends Component {
state: State = {
person: { fname: 'John', lname: 'Doe' },
}
render() {
return (
<PersonDetails person={this.state.person} />
)
}
}
在组件的props
中:
// components/PersonDetails.js
import type { Person } from '../types'
type Props = {|
person: Person,
|}
// stateful syntax
class PersonDetails extends Component {
props: Props
render() {
const { person } = this.props
return (
<div>
<span>{person.fname}</span>
<span>{person.lname}</span>
</div>
)
}
}
// stateless syntax
const PersonDetails = ({ person }: Props) => (
<div>
<span>{person.fname}</span>
<span>{person.lname}</span>
</div>
)
假设我有一个 App
组件,其状态由一个对象组成,该对象的形状由以下流类型给出:
type Person = {
fname: string,
lname: string
};
为了断言我的组件的状态确实是 Person
类型,我在 getInitialState
中创建了一个人工局部变量,以便我可以注释类型:
const App = React.createClass({
getInitialState: function() {
const person : Person = {fname: 'John', lname: 'Doe'};
return {person: person};
}
, render: function() {
return (
<PersonDetails person={this.state.person}/>
);
}
});
以上工作(尽管必须声明 const person
是一个小的不便)。
当我希望将该状态作为另一个组件的 属性 传递时,问题就出现了。在那种情况下,我没有找到其他解决方案,只能使用 React 的 PropTypes
API:
const PersonDetails = React.createClass({
propTypes: {
person: React.PropTypes.shape({fname: React.PropTypes.string.isRequired,
lname: React.PropTypes.string.isRequired}).isRequired
},
render: function() {
return (
<div>
<span>{this.props.person.fname}</span>
<span>{this.props.person.lname}</span>
</div>
);
}
});
这显然不是 DRY,而且我使用两种不同的方法来提供静态类型信息(Flow 和 React.PropTypes API)。
有没有办法让PersonDetails
组件重用Person
的类型声明?
我发现的唯一方法是使用正确的 类(不是 React 类型):
class Person {
fname: string;
lname: string;
constructor(fname: string, lname: string) {
this.fname = fname;
this.lname = lname;
}
};
const PersonDetails = React.createClass({
propTypes: {
person: React.PropTypes.instanceOf(Person).isRequired
},
render: function() {
return (
<div>
<span>{this.props.person.fname}</span>
<span>{this.props.person.lname}</span>
</div>
);
}
});
const App = React.createClass({
getInitialState: function() {
const person : Person = new Person('John', 'Doe');
return {person: person};
}
, render: function() {
return (
<PersonDetails person={this.state.person}/>
);
}
});
export default App;
… 虽然上面成功地重用了定义,但我不清楚何时应该使用 Flow 类型而不是 类 来静态类型检查我的组件。另外,我不确定这两种方法是否真的等同(例如,在能够表达值的可空性方面)。
声明你的类型一次并导出它:
// types/index.js
export type Person = {|
fname: string,
lname: string,
|}
然后到处重复使用它。
在组件的state
中:
// App.js
import type { Person } from './types'
type State = {|
person: Person,
|}
class App extends Component {
state: State = {
person: { fname: 'John', lname: 'Doe' },
}
render() {
return (
<PersonDetails person={this.state.person} />
)
}
}
在组件的props
中:
// components/PersonDetails.js
import type { Person } from '../types'
type Props = {|
person: Person,
|}
// stateful syntax
class PersonDetails extends Component {
props: Props
render() {
const { person } = this.props
return (
<div>
<span>{person.fname}</span>
<span>{person.lname}</span>
</div>
)
}
}
// stateless syntax
const PersonDetails = ({ person }: Props) => (
<div>
<span>{person.fname}</span>
<span>{person.lname}</span>
</div>
)