React - 当值具有不同的类型时,如何在更改事件中将多个输入值传递给child(并不总是e.target.value)?

我有多个输入字段和1个react-select下拉字段 . 我在我的父组件中创建了一个方法,该方法使用输入中的值设置状态,将其传递给应调用方法的子项 . 我的问题是react-select不接受值,而是像这样的对象:

{value: 'xy', name:'x', label: 'y'}

通常我的onChange事件处理程序中的函数看起来像这样(当传递多个值时):

在父母:

testing(e) {
    this.setState({
        [e.target.name]: e.target.value
    })
}

在孩子:

<input type="text" name="maxfare" onChange={this.onChange}/>
...
onChange(e){
   var value = [e.target.name] = e.target.value;
   this.props.onChange(value);
}
...

但是,我的输入字段采用:

e.target.value

我的选择下拉列表需要整个'e' - 而不是e.target.value . 我试图在子组件2参数中传递我的onChange函数,在父类中使用2调用我的方法,但这不起作用 . 任何帮助都会很棒!我的代码如下(相关部分 - 如果我忘记了您认为重要的内容,请告诉我) . PS . 我想过有2个onChange函数,一次传递我的选择下拉值,第二个传递其余的,但后来我需要将2个onChange方法传递给孩子,我相信那是不可能的反应?!谢谢!!:

家长:

...
 onChangeT(selectValue, value) {
    this.setState({
        origin: selectValue,
        maxfare: value
        ...       
    })
}
render(){
....
  <Parent cities={this.state.citiesToSelect} origin={this.state.origin} maxfare={this.state.maxfare} onChange={this.onChangeT}/>
...
}

儿童:

....
onChangeC(e){
    var value = [e.target.name] = e.target.value;
    this.props.onChange(e, value);
    console.log("name",  name)
}
....
<Select
     onChange={this.onChangeC}
     labelKey='name'
     value={this.props.origin}
     options={this.props.cities}                 
/>
<input type="text" name="maxfare" onChange={this.onChangeC}/>

回答(2)

2 years ago

我们希望能够在父母中执行此操作

onChange = (name, value) => {
    this.setState({[name]: value});
  }

我们修复"wiring"的子项 onChange 来做到这一点,用 namevalue 引发 onChange . 包装 react-select 并为父级提供一致的界面 .

表单示例

import * as React from 'react';
import Input from './Input';
import Select from './Select';

export default class Form extends React.Component {
  state = {
    input: '',
    select: '',
    options: ['A', 'B', 'C']
  };

  onChange = (name: string, value: string) => {
    this.setState({[name]: value});
  }

  render() {
    return (
      <form>
        <Input
          label="Surname"
          name={'input'}
          value={this.state.input}
          onChange={this.onChange}
        />
        <Select
          label="Grade"
          name={'select'}
          value={this.state.select}
          options={this.state.options}
          onChange={this.onChange}
        />
      </form>
    );
  }
}

输入示例

import * as React from 'react';

export default class Input extends React.Component {
  onChange = (e) => {
    const {onChange, name} = this.props;
    if (onChange) {
      onChange(name, e.currentTarget.value);
    }
  }

  render() {
    return (
      <div>
        <label>{this.props.label}</label>
        <input
          type="text"
          name={this.props.name}
          value={this.props.value}
          onChange={this.onChange}
        />
      </div>
    );
  }
}

和DOM本机<Select />示例

import * as React from 'react';

export default class Select extends React.Component {
  onChange = (e) => {
    const {onChange, name} = this.props;
    if (onChange) {
      onChange(name, e.currentTarget.value);
    }
  }

  render() {
    return (
      <div>
        <label>{this.props.label}</label>
        <select
          name={this.props.name}
          value={this.props.value}
          onChange={this.onChange}
        >
          {this.props.options.map(o => <option key={o}>{o}</option>)}
        </select>
      </div>
    );
  }
}

2 years ago

react-select不返回本机事件或本机事件的类似对象形状这一事实迫使您规范化从其返回的对象的形状 . 您可以通过将react-select的 Select 组件与您自己的组件包装在一起并为您的用例返回自定义对象来实现 .

在这个例子中,我们试图规范化 onChange 事件对于输入和 Select 的行为 . 我们将首先检查返回的对象是否具有 target 键,如果我们知道这是我们正在处理的本机事件,我们将根据输入的名称及其值设置状态(具体如何在你的例子中做到了) .

如果我们没有 target 键,那么我们可以处理不同类型的事件 .
我们将检查是否得到一个 selectedValue 键(只是你自己之间的约定,你可以根据需要更改键),然后我们将按照我们收到的 nameselectedValue 设置状态 .

只有当您将名称向上传递时,这才有效 .
因此,您需要从自定义 Select 组件返回的对象应如下所示:

{name: this.props.name, selectedValue } 
// where selectedValue is the object received from the real Select component

这是一个运行的例子:

const options = [
  { value: 'one', label: 'One' },
  { value: 'two', label: 'Two' },
]

const moreOptions = [
  { value: 'mike', label: 'johnson' },
  { value: 'lynda', label: 'bog' },
]

class MySelect extends React.Component {

  handleChange = selectedValue => {
    const { name, onChange } = this.props;
    onChange({ name, selectedValue });
  }

  render() {
    const { options, value, ...rest } = this.props;
    return (
      <Select
        {...rest}
        value={value}
        onChange={this.handleChange}
        options={options}
      />
    );
  }
}


class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      option1: '',
      option2: '',
      value1: 1,
      value2: '',
      value3: 3,
    }
  }

  handleChange = e => {
    let nextState;
    if (e.target) {
      const { name, value } = e.target;
      nextState = { [name]: value };
    } else if (e.selectedValue) {
      const { name, selectedValue } = e;
      nextState = { [name]: selectedValue };
    }

    this.setState(nextState);
  }

  render() {
    const { value1, value2, value3, option1, option2 } = this.state;
    return (
      <div>
        <MySelect
          value={option1.value}
          onChange={this.handleChange}
          options={options}
          name="option1"
        />
        <div>
          <span>input1 </span>
          <input value={value1} name="value1" onChange={this.handleChange} />
        </div>
        <div>
          <span>input2 </span>
          <input value={value2} name="value2" onChange={this.handleChange} />
        </div>
        <div>
          <span>input3 </span>
          <input value={value3} name="value3" onChange={this.handleChange} />
        </div>

        <MySelect
          value={option2.value}
          onChange={this.handleChange}
          options={moreOptions}
          name="option2"
        />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://unpkg.com/prop-types@15.5.10/prop-types.js"></script>
<script src="https://unpkg.com/classnames@2.2.5/index.js"></script>
<script src="https://unpkg.com/react-input-autosize@2.0.0/dist/react-input-autosize.js"></script>
<script src="https://unpkg.com/react-select/dist/react-select.js"></script>
<link rel="stylesheet" href="https://unpkg.com/react-select/dist/react-select.css">
<div id="root"></div>