https://qiita.com/y_ohr/items/18c2f658013906f3849c の続き
概要
TypeScript Deep DiveのReact JSXをやってみる。
https://typescript-jp.gitbook.io/deep-dive/tsx/react
https://basarat.gitbooks.io/typescript/docs/jsx/react.html
React JSX Tip: Accept a component that can act on props and be rendered using JSX
関数コンポーネントやクラスコンポーネントをpropsに設定できる?
正直よくわかってないです。
とりあえず写経。
BabelでException発生。
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello React!</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
<script type="text/babel">
const X: React.Component<Props> = foo; // from somewhere
// Render X with some props:
ReactDOM.render(<X {...props}/>, document.getElementById('root'));
</script>
React JSX Tip: Generic components
こちらもBabelでException発生。
雰囲気だけ。
index.html
<!-- 省略 -->
<script type="text/babel">
/** A generic component */
type SelectProps<T> = {item: T[] }
class Select<T> extends React.Component<SelectProps<T>, any> { }
/** Usage */
const Form = () => <Select<string> items{['a','b']} />;
ReactDOM.render(Form, document.getElementById('root'));
</script>
Generic functions
アロージェネリック関数の場合は、<T extends {}>
と書く。
index.html
<!-- 省略 -->
<script type="text/babel">
function foo<T>(x: T): T { return x; } // OKay
const foo = <T>(x: T) => x; // ERROR : unclosed `T` tag
const foo = <T extends {}>(x: T) => x; // Okay
</script>
React Tip: Strongly Typed Refs
Use.exampleRefに型を設定しているということ?
index.html
<!-- 省略 -->
<script type="text/babel">
class Example extends React.Component {
example() {
// ... something
}
render() { return <div>Foo</div> }
}
class Use {
exampleRef: Example | null = null;
render() {
return <Example ref={exampleRef => this.exampleRef = exampleRef } />
}
}
</script>
レンダー付き。
index.html
<!-- 省略 -->
<script type="text/babel">
class FocusingInput extends React.Component<{ value: string, onChange: (value: string) => any }, {}>{
input: HTMLInputElement | null = null;
render() {
return (
<input
ref={(input) => this.input = input}
value={this.props.value}
onChange={(e) => { this.props.onChange(e.target.value) } }
/>
);
}
focus() {
if (this.input != null) { this.input.focus() }
}
}
ReactDOM.render(<FocusingInput />, document.getElementById('root'));
</script>
Type Assertions
as Foo
を使う。
実装サンプルはなし。
Default Props
static defaultProps
で初期値を指定できるという話?
index.html
<!-- 省略 -->
<script type="text/babel">
class Hello extends React.Component<{
/**
* @default 'TypeScript'
*/
compiler?: string,
framework: string
}> {
static defaultProps = {
compiler: 'TypeScript'
}
render() {
const compiler = this.props.compiler;
return (
<div>
<div>{compiler}</div>
<div>{this.props.framework}</div>
</div>
);
}
}
ReactDOM.render(
<Hello framework="React" />, // TypeScript React
document.getElementById("root")
);
</script>
FunctionComponentの場合。
index.html
<!-- 省略 -->
<script type="text/babel">
const Hello: React.FunctionComponent<{
/**
* @default 'TypeScript'
*/
compiler?: string,
framework: string
}> = ({
compiler = 'TypeScript', // Default prop
framework
}) => {
return (
<div>
<div>{compiler}</div>
<div>{framework}</div>
</div>
);
};
ReactDOM.render(
<Hello framework="React" />, // TypeScript React
document.getElementById("root")
);
</script>
感想
- 結構難解な印象。慣れの問題?
- Reactが分からないのか、TypeScriptが分からないのか、分からなくなる。
- 少し自由に書いて理解を深めたい。
以上