1

I can add e.target.value for taking a value from Input, but I don't know why handleChange() could not take input value correctly, it will get title:SyntheticBaseEvent, on the Option Part, it will receive a correct value as 0,1,2,3. I am using Antd UI. Did I miss something in my code, please help me to resolve it?

  handleChange = (type, v) => {
    this.data.Schedule[type] = v;
  };
      <Input
        placeholder="Please Type Your Title"
        className="todo-ipt"
        value={this.state.curSchedule.title}
        onChange={this.handleChange.bind(this, 'title')}
      />
    </div>
    <Select
      placeholder="Please Type Schedule Type"
      type="date"
      className="todo-select"
      defaultValue={this.state.curSchedule.type}
      onChange={this.handleChange.bind(this, 'type')}
    >
      <Option value="0">Daily</Option>
      <Option value="1">Weekly</Option>
      <Option value="2">Monthly</Option>
      <Option value="3">Quarterly</Option>
    </Select>
R. Oosterholt
  • 7,720
  • 2
  • 53
  • 77
Daniel Wang
  • 57
  • 1
  • 5
  • 1
    You are calling `bind` on an arrow function whose `this` can't be bound. `title` is then prepended to the intrinsically passed arguments (event), so `type` is 'title', `v` is `event` and `this` is unchanged (so remains the outer scope in which the arrow function was declared). see: [Can you bind 'this' in an arrow function?](https://stackoverflow.com/questions/33308121/can-you-bind-this-in-an-arrow-function), and [Passing event to event handler](https://stackoverflow.com/questions/65887723/passing-event-to-event-handler/65888180#65888180) – pilchard Jan 26 '21 at 23:25
  • Thanks pilchard, on the Option Part, it will receive a correct value as 0,1,2,3. As you mentioned that should pass event as well? – Daniel Wang Jan 27 '21 at 03:42
  • The antd component doesn't forward the value, but does pass the event.) To make this work with a single handler you would need to account for this inconsistency from antd, but it will be clearer to write separate Input and Select handlers. – pilchard Jan 27 '21 at 10:58

1 Answers1

1

The antd <Select> onChange method passes the selected value, but it doesn't forward the event. (where as the <Input> component doesn't pass the value, but does forward the event.)

To make this work with a single handler using bind() would require you to account for this inconsistency from antd.

const handleChange = (type, v, e) => {
  const value = v !== null ? v : e.target.value; // handle the inconsistent antd arguments
  setCurSchedule(prev => ({ ...prev, [type]: value }))
};

...

<Input
...
  onChange={handleChange.bind(null, 'title', null)}
  // 'v' will be null, 'e' will be the implicitly passed event.
/>

<Select
  ...
  onChange={handleChange.bind(null, 'type')} 
  // 'v' implicitly passed, 'e' will be the selected option (not the event)
>

const { Input, Select } = antd;

const App = () => {
  const [curSchedule, setCurSchedule] = React.useState({ type: 'Daily' });
  console.log(curSchedule);

  const handleChange = (type, v, e) => {
    console.clear();
    console.log('type: ', type, ' v: ', v, ' e: ', e.target);
    const value = v !== null ? v : e.target.value; // handle the inconsistent antd arguments
    setCurSchedule(prev => ({ ...prev, [type]: value }))
  };

  return (
    <div>
      <div>
        <Input
          placeholder="Please Type Your Title"
          className="todo-ipt"
          value={curSchedule.title}
          onChange={handleChange.bind(null, 'title', null)}
        />
      </div>
      <Select
        placeholder="Please Type Schedule Type"
        type="date"
        className="todo-select"
        defaultValue={curSchedule.type}
        onChange={handleChange.bind(null, 'type')}
      >
        <Option value="0">Daily</Option>
        <Option value="1">Weekly</Option>
        <Option value="2">Monthly</Option>
        <Option value="3">Quarterly</Option>
      </Select>
    </div>
  )
}

ReactDOM.render(
  <App />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<!--AntD -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/antd/4.11.2/antd.min.js" integrity="sha512-po2baibyaVyDwINF7gijO2Zbd9HBQDnd81yJNghcwuU+bjb79Qkaf4zopd2mkQJ33aBHLIifLeGwV7+QiyV3wQ==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/antd/4.11.2/antd.min.css" integrity="sha512-gs6VDTwxBRKAfKFQbN+UR2wCkNoFnPrvLcsEwGtzDDG1Wuwx5w/UhjsnMwm27En67jU0M04ofj8IIctaBmaU+A==" crossorigin="anonymous" />

<div id="react"></div>

But given the inconsistent implementation from antd it is much clearer to pass an arrow function to the the onChange which explicitly displays the differences in the implicitly passed arguments.

<Input
...
  onChange={(event) => handleChange('title', event.target.value)}
/>

<Select
...
  onChange={(value) => handleChange('type', value)}
>

const { Input, Select } = antd;

const App = () => {
  const [curSchedule, setCurSchedule] = React.useState({ type: 'Daily' });
  
  console.log('curSchedule: ', curSchedule);

  const handleChange = (type, value) => {
    console.clear();
    console.log('type: ', type, ' value: ', value);
    setCurSchedule(prev => ({ ...prev, [type]: value }))
  };

  return (
    <div>
      <div>
        <Input
          placeholder="Please Type Your Title"
          className="todo-ipt"
          value={curSchedule.title}
          onChange={(event) => handleChange('title', event.target.value)}
        />
      </div>
      <Select
        placeholder="Please Type Schedule Type"
        type="date"
        className="todo-select"
        defaultValue={curSchedule.type}
        onChange={(value) => handleChange('type', value)}
      >
        <Option value="0">Daily</Option>
        <Option value="1">Weekly</Option>
        <Option value="2">Monthly</Option>
        <Option value="3">Quarterly</Option>
      </Select>
    </div>
  )
}

ReactDOM.render(
  <App />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<!--AntD -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/antd/4.11.2/antd.min.js" integrity="sha512-po2baibyaVyDwINF7gijO2Zbd9HBQDnd81yJNghcwuU+bjb79Qkaf4zopd2mkQJ33aBHLIifLeGwV7+QiyV3wQ==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/antd/4.11.2/antd.min.css" integrity="sha512-gs6VDTwxBRKAfKFQbN+UR2wCkNoFnPrvLcsEwGtzDDG1Wuwx5w/UhjsnMwm27En67jU0M04ofj8IIctaBmaU+A==" crossorigin="anonymous" />

<div id="react"></div>
pilchard
  • 12,414
  • 5
  • 11
  • 23