React-根据react-select selectedOption

时间:2019-01-28 22:55:20

标签: javascript reactjs

我正在使用react-select来呈现两种类型的“作业”选项。用户可以从下拉菜单中选择其中一个选项。根据所选的选项,它们应呈现包含更多输入值的不同div。输入值取决于selectedOption。我有两个带有render方法的类组件,这些组件应显示与jobType

相对应的不同输入
class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      selectedOption: null
    };

    this.onChange = this.onChange.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  onChange = e => {
    this.set({ [e.target.name]: e.target.value });
    console.log([e.target.value]);
  };

  handleChange = selectedOption => {
    this.setState({ selectedOption });
    console.log("Option selected: ", selectedOption);
  };

  render() {
    const { selectedOption } = this.state;
    return (
      <div>
        <fieldset>
          <legend>Parameters</legend>
          <label htmlFor="jobType" style={{ display: "block" }}>
            jobType:
          </label>
          <div>
            <Select
              value={selectedOption}
              onChange={this.handleChange}
              options={options}
              placeholder="Select a jobType..."
              isSearchable={options}
            />
          </div>
        </fieldset>
        <div>
          {selectedOption === "Batch" ? (
            <BatchParams />
          ) : selectedOption === "Streaming" ? (
            <StreamingParams />
          ) : null}
        </div>
      </div>
    );
  }
}

因此,假设从下拉列表中选择Streaming选项时,应呈现以下类组件:

class StreamingParams extends React.Component {
      constructor(props) {
        super(props);

        this.state = {
          maxHits: 1
        };
        this.handleMaxHitsChange = this.handleMaxHitsChange.bind(this);
      }

      handleMaxHitsChange = e => {
        this.set({ [e.target.name]: e.target.valu });
      };
      render() {
        return (
          <div>
            <label>maxHits:</label>
            <input
              type="number"
              name="maxHits"
              onChange={this.handleMaxHitsChange}
              placeholder="1"
              min="1"
              step="1"
              required
            />
          </div>
        );
      }
    }

我不能完全渲染其他输入框,不确定在这里是否采用正确的方法。我的问题中包含了codesandbox

3 个答案:

答案 0 :(得分:2)

仅需更改三元运算符:找到更新的代码框here

在三元运算符中,您将必须检查this.state.selectedOption.value,因为这是您的选项值的存储位置。

{!this.state.selectedOption ? 
    null : 
    this.state.selectedOption.value === "batch" ? (
        <BatchParams />
    ) : (
        <StreamingParams />
    )
}

此外,您必须首先检查null,因为这是在选择中未设置任何元素时为this.state.selectedOption获得的初始值。

答案 1 :(得分:2)

因此,看来this.state.selectedOption中设置的值是一个具有valuelabel字段的对象。

enter image description here

因此您需要取消这些。而不是这样做

          {selectedOption === "Batch" ? (
            <BatchParams />
          ) : selectedOption === "Streaming" ? (
            <StreamingParams />
          ) : null}

这样做

          {selectedOption && selectedOption.value === "batch" ? (
            <BatchParams />
          ) : selectedOption && selectedOption.value === "streaming" ? (
            <StreamingParams />

如果进行本地化或翻译,则应选择value而不是label

https://codesandbox.io/s/ll5p30nx5q

答案 2 :(得分:1)

问题是您必须在selectedOptions中获取值,并将该值分配给事件处理程序setState中的selectedOption。您正在尝试分配一个对象,因此是问题所在。也已在沙箱中进行了更改。希望对您有所帮助。

import React from "react";
import ReactDOM from "react-dom";
import Select from "react-select";

import "./styles.css";

const options = [
  { value: "batch", label: "Batch" },
  { value: "streaming", label: "Streaming" }
];

class BatchParams extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      batchNumber: 1
    };
    this.handleBatchNumChange = this.handleBatchNumChange.bind(this);
  }

  handleBatchNumChange = e => {
    this.set({ [e.target.name]: e.target.valu });
  };
  render() {
    return (
      <div>
        <label>batchNumberSize:</label>
        <input
          type="number"
          name="batchNumberSize"
          onChange={this.handleBatchNumChange}
          placeholder="1"
          min="1"
          step="1"
          required
        />
      </div>
    );
  }
}

class StreamingParams extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      maxHits: 1
    };
    this.handleMaxHitsChange = this.handleMaxHitsChange.bind(this);
  }

  handleMaxHitsChange = e => {
    this.set({ [e.target.name]: e.target.valu });
  };
  render() {
    return (
      <div>
        <label>maxHits:</label>
        <input
          type="number"
          name="maxHits"
          onChange={this.handleMaxHitsChange}
          placeholder="1"
          min="1"
          step="1"
          required
        />
      </div>
    );
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      selectedOption: null
    };

    this.onChange = this.onChange.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  onChange = e => {
    this.set({ [e.target.name]: e.target.value });
    console.log([e.target.value]);
  };

  handleChange =( {value}) => {
    console.log(value);
    this.setState({ selectedOption: value });
    
  };

  render() {
    const { selectedOption } = this.state;
    return (
      <div>
        <fieldset>
          <legend>Parameters</legend>
          <label htmlFor="querySchemaName" style={{ display: "block" }}>
            jobType:
          </label>
          <div>
            <Select
              value={selectedOption}
              onChange={this.handleChange}
              options={options}
              placeholder="Select a jobType..."
              isSearchable={options}
            />
          </div>
        </fieldset>
        <div>

          {selectedOption === "batch" && <BatchParams /> }
          {selectedOption === "streaming" && <StreamingParams />}
        </div>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);