输入 onChange() 事件未被调用

Input onChange() event is not called


渲染()

render() {
    // Custom Menu
    const arrowsMenu = (
    <Menu compact size='tiny'>
      <Menu.Item as='a' onClick={ this.decreaseNumber.bind(this) }>
        <Icon name='chevron left' size='small' />
      </Menu.Item>
      <Menu.Item as='a' onClick={ this.increaseNumber.bind(this) }>
        <Icon name='chevron right' size='small' />
      </Menu.Item>
    </Menu>
    );

    return (
      <Input value={ this.state.value } type="number" label={ arrowsMenu } placeholder="Raplece ma" onChange={ this.onChange.bind(this) } />
      );
  }

自定义菜单使用这两个函数:

decreaseNumber(e) {
    this.setState({
      value: this.state.value - 1
    });
  }

  increaseNumber(e) {
    this.setState({
      value: this.state.value + 1
    });
  }

onChange

你可以放置任何东西。

onChange(e) {
    console.log('====================================');
    console.log('Hello pals');
    console.log('====================================');
  }

问题是

每当我 Menu 推箭头 时, InputonChange() 事件是 不触发。但是输入改变

(当然是因为this.state.value变量在state里变了)

如果我对原来的箭头做同样的事情,当然,值会改变。

为什么会这样,我该如何解决?

onChange 仅在用户进入输入组件并与其交互以更改值时调用(例如,如果他们输入新值)。如果您通过其他途径以编程方式更改值(在您的示例中通过自定义菜单更改它),则不会调用 onChange

这是按预期设计工作的。

如果您想触发 onChange,请从您的 increaseNumberdecreaseNumber 方法中调用它。

您可以使用您想要的任何代码调用 onChange,但是如果您想要反映新值,您需要根据事件的新输入值设置状态。
至于 decreaseNumberincreaseNumber 你也需要改变状态但是在这里你正在进行计算所以你需要确保它是一个数字(或将它转换为数字)因为你得到一个字符串从活动回来。

工作示例:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 0
    };
  }

  onChange = e => this.setState({value: e.target.value});
  increaseNumber = () => this.setState({value: Number(this.state.value) + 1});
  decreaseNumber = () => this.setState({ value: Number(this.state.value) - 1 });

  render() {
    const { value } = this.state;
    return (
      <div>
        <button onClick={this.decreaseNumber}>-</button>
        <input type="number" value={value} onChange={this.onChange}/>
        <button onClick={this.increaseNumber}>+</button>
      </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>
<div id="root"></div>

编辑 要触发 onChange 处理程序,只需调用 this.onChange 但请注意,您不能像本机事件处理程序那样传递事件,但您可以传递一个简单的 object 来模拟正常的 [=21] =] object 与 target.value.
另一种选择是尝试通过 ref 触发它,但请记住,在某些情况下它可能会导致无限循环。 编辑示例:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 0
    };
  }

  onChange = (e) => {
    this.setState({ value: e.target.value });
    console.log('change', e.target.value);
  }
  increaseNumber = () => {
    const { value } = this.state;
    const nextValue = Number(value) + 1;
    const changeEvent = {
      target: {
        value: nextValue
      }
    };
    this.onChange(changeEvent);
  }

  decreaseNumber = () => {
    const { value } = this.state;
    const nextValue = Number(value) - 1;
     const changeEvent = {
      target: {
        value: nextValue
      }
    };
    this.onChange(changeEvent);
  }

  render() {
    const { value } = this.state;
    return (
      <div>
        <button onClick={this.decreaseNumber}>-</button>
        <input type="number" value={value} onChange={this.onChange} />
        <button onClick={this.increaseNumber}>+</button>
      </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>
<div id="root"></div>

编辑 #2
作为您评论的跟进:

list's value is its content/children. If some of the children change, then list changes with them as well

好吧,这有一个简单的解决方案,您可以使用 ref(就像我在回答的第一部分中提到的那样)并使用 bubbles:true 发送一个事件,这样它就会冒泡所有一直到 parents.
使用您的新示例代码:

class App extends React.Component {
 liOnChange(e) {
  console.log('listed item/items changed');
 }
  
  inputOnChange(e) {
   console.log('input changed');
  }
  handleClick(e){
    var event = new Event("input", { bubbles: true });
    this.myInput.dispatchEvent(event);
  }
 render() {
   return(
   <div>
       <ul>
         <li onChange={this.liOnChange.bind(this)}>
           <input ref={ref => this.myInput = ref} type='text'onChange={this.inputOnChange.bind(this)}/>
            <button onClick={this.handleClick.bind(this)}>+</button>
         </li>
        </ul>
      </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>
<div id="root"></div>

我一般不喜欢使用参考,但有时你需要它们。