簡體   English   中英

React:以編程方式更改組件值不會觸發 onChange 事件

[英]React: programmatically change component value doesn't trigger onChange event

我在 React 組件中有一個選擇字段,它的值是通過組件狀態設置的,並且有一個附加到 onChange 事件的函數。 如果我手動更改選擇字段值,則會觸發 onChange 事件,但如果我通過更改另一個函數的狀態值來更改它,則不會。 有沒有辦法以編程方式觸發事件?

編輯:

以下是我需要實現的基本示例。 這個想法是,當 handleChange1() 更改 state.val2 的值(並因此更改在第二個選擇字段上選擇的選項)時,handleChange2() 也會被觸發,因此合成事件被傳遞給父函數(在實際代碼,選擇字段是另一個組件):

class Component extends React.Component {
  state = {
    val1: 1,
    val2: 1,
  }

  handleChange1 = (event) => {
    const val2 = event.target.value === 3 ? 1 : null;
    this.setState({
      val1: event.target.value,
    });
    if (event.target.value === 3) {
      this.setState({
        val2: 1,
      });
    }
    this.props.parentFunction(event);
  }

  handleChange2 = (event) => {
    this.setState({
      val2: event.target.value,
    });
    this.props.parentFunction(event);
  }

  render() {
    return (
        <div>
          <select value={val1} onChange={this.handleChange1}>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
          </select>
          <select value={val2} onChange={this.handleChange2}>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
          </select>
        </div>
    );
  }
};

您應該將輸入包裝在專用組件中以自定義所需的行為。 就像是 :

class Input extends React.Component {

 constructor(props){
    super(props);
    this.state = {
      value: props.value
    }
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      value: nextProps.value,
    });
    this.props.onChange(nextProps.value);
  }

  updateValue(ev) {
    this.setState({
      value: ev.target.value,
    });
    this.props.onChange(ev.target.value);
  }

  render() {
    return (
      <input
        onChange={this.updateValue.bind(this)}
        value={this.state.value}
        {...this.props}
      />
    )
  }
}

並使用它:

<Input value="test" onChange={someAction} />

請注意,由於您的輸入處於受控狀態,因此 value 不能為 null 或 undefined。

是的,有辦法! React 具有防止onChange在以編程方式設置輸入值時觸發的邏輯,但它可以解決。

代替:

input.value = 'foo';

做這個:

const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
setter.call(input, 'foo');
input.dispatchEvent(new Event('input', { bubbles: true }));

查看這篇文章以獲得完整的解釋。


如果不清楚, input的值是您將從 ref 獲得的 DOM 元素。 例子:

function SomeComponent({ onChange }) {
  const ref = useRef();

  useEffect(() => {
    setInterval(() => {
      const input = ref.current;
      const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
      setter.call(input, new Date().toISOString());
      input.dispatchEvent(new Event('input', { bubbles: true }));
    }, 10000);
  });

  return <input type="text" ref="ref" onChange={onChange} />;
}

此組件將使用日期字符串更新其輸入並每 10 秒使用新值觸發onChange回調。

我遇到了同樣的問題,幸運的是@goouroujo的答案對我有用,但是當我檢查文檔時,它的名稱已更改為UNSAFE_componentWillReceiveProps()並且文檔說:

筆記

這個生命周期以前被命名為componentWillReceiveProps 該名稱將繼續有效,直到版本 17。使用rename-unsafe-lifecycles codemod自動更新您的組件。

有關UNSAFE_componentWillReceiveProps() 的更多詳細信息

另一種解決方案是在組件上設置一個key ,以便 react 可以

創建一個新的組件實例而不是更新當前的組件實例。

有關帶鑰匙的完全不受控制的組件的更多詳細信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM