C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

state のリフトアップ2

こちらの続きです。
state のリフトアップ1 - C#ATIA

苦労の末、劇的にショボいComboBox(selectタグ)が出来ました。
f:id:kandennti:20210401173341p:plain
選択した結果がComboBoxの下に表示されます。
表示させたいのではなくて、後の処理的に取得したいための代案です。

こんな感じです。

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  constructor(){
    super()
 
    this.state = {
      toolList:[
        { type: "選択して", dia: "下さい" },
        { type: "DR", dia: 6.8 },
        { type: "TP", dia: 8.0 },
        { type: "EM", dia: 10.0 },
      ],
      selectedValue: null
    }
  }

  render(){
    const tools = this.state.toolList

    return (
      <div className="App">
        <h1>Select Tool</h1>
        <select
          id="tool"
          name="tool"
          value={this.state.selectedValue}
          onChange={ e => this.setState({selectedValue: e.target.value}) }>
          {tools.map( tool =>
            <option
              value={[tool.type , tool.dia]}
            >
                {tool.type}{tool.dia}
            </option>
          )}
        </select>
        <h2>{this.state.selectedValue}</h2>
      </div>
    );
  }
}

export default App;

色々なものが足りませんが。

単一のコンポーネントがイケていない為、ComboBoxのみの
コンポーネントを作りつつ、state のリフトアップを行いたいので
SelectTool.jsを新たに作成しました。

import React from 'react';

class SelectTool extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      toolList: props.tools,
      selectTool: props.tools[0]
    };
    this.onChange = this.onChange.bind(this);
  }

  onChange(e){
    console.log(e.target.value);
    this.setState({ selectTool: e.target.value});
  }

  render() {
    var options = this.state.toolList.map( tool =>
      <option
        value={[tool.type , tool.dia]}
      >
          {tool.type}{tool.dia}
      </option>
    );
  
    return (
      <select
        value={this.state.selectTool}
        onChange={this.onChange}>
        {options}
      </select>
    )
  }
}

export default SelectTool;

これを受け止めるため、App.jsを修正しました。

import React from 'react';
import './App.css';
import SelectTool from './components/SelectTool';

class App extends React.Component {
  constructor(){
    super()
 
    this.state = {
      toolList:[
        { type: "選択して", dia: "下さい" },
        { type: "DR", dia: 6.8 },
        { type: "TP", dia: 8.0 },
        { type: "EM", dia: 10.0 },
      ],
      selectTool: null
    }
  }

  render(){
    const tools = this.state.toolList

    return (
      <div className="App">
        <h1>Select Tool</h1>
        <SelectTool
          tools = {tools} 
        />
        <h2>{this.state.selectedValue}</h2>
      </div>
    );
  }
}

export default App;

結果
f:id:kandennti:20210401174618p:plain
選択要素が表示されません。そりゃそれを書いていないからです・・・。
親から子には伝えられるのですが、子から親にどうやって・・・。

コンポーネント間で情報の受け渡し – React入門 - to-R Media
こちらを見ると、Ref関数を使用するやり方が記載されているのですが、
あまり推奨されていないようですし、警告も出てしまいます。
イベントもリフトアップすれば良い気もするの出すが・・・。