かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

TypeScript JSXでラジオボタンのリストを作る

onChangeで選択された値を渡してくれるコールバックと、defaultValueで、初期選択の値を設定できるみたいな感じです。 ラジオボタンのリストの要素はoptionタグで指定できる雰囲気でいってみましょう。

まず、プロパティを定義します。

interface RadioListProps extends React.Props<{}> {
    defaultValue?: string;
    onChange?: (value: string) => void;
}

ステートには、選択中の値を持たせることにします。

interface RadioListState {
    value: string;
}

あとはrenderで割と頑張る。ポイントは、React.Children.forEachで子要素をループ回してるところです。

class RadioList extends React.Component<RadioListProps, RadioListState> {
    constructor(props: RadioListProps) {
        super(props);
        this.state = { value: this.props.defaultValue } as RadioListState;
    }

    private handleChanged(value: string, e: React.SyntheticEvent) {
        this.props.onChange(value);
        this.setState({ value: value } as RadioListState);
    }

    render() {
        var radios = new Array<React.ReactElement<any>>();
        React.Children.forEach(this.props.children, (option: React.ReactElement<{ value: string; label: string; }>, index) => {
            radios.push(<div>
                    <label>
                        <input
                            type="radio"
                            value={option.props.value}
                            checked={this.state.value === option.props.value}
                            onChange={this.handleChanged.bind(this, option.props.value) } />
                        {option.props.label}
                    </label>
                </div>);
        });

        return <span>{radios}</span>;
    }
}

こんな感じに使えます。

ReactDOM.render(<RadioList onChange={x => console.log(x) } defaultValue="B">
        <option value="A" label="Aです" />
        <option value="B" label="Bです" />
        <option value="C" label="Cです" />
    </RadioList>,
    document.getElementById("content"));