programing

반응: 입력 값이 상태별로 변경되는 경우 onChange를 트리거합니까?

minimums 2023. 3. 9. 21:57
반응형

반응: 입력 값이 상태별로 변경되는 경우 onChange를 트리거합니까?

편집: 버튼을 클릭한 경우에만 handleChange를 호출하지 않습니다.handle Click과는 관계가 없습니다.@shubhakhatri 답변의 코멘트에서 예를 들었습니다.

상태에 따라 입력 값을 변경하고 싶은데 값이 변경되지만 트리거되지 않습니다.handleChange()방법.트리거 방법handleChange()방법?

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
    value: 'random text'
    }
  }
  handleChange (e) {
    console.log('handle change called')
  }
  handleClick () {
    this.setState({value: 'another random text'})
  }
  render () {
    return (
      <div>
        <input value={this.state.value} onChange={this.handleChange}/>
        <button onClick={this.handleClick.bind(this)}>Change Input</button>
      </div>
    )
  }
}

ReactDOM.render(<App />,  document.getElementById('app'))

다음은 코드 페이지 링크입니다.http://codepen.io/madhurgarg71/pen/qrbLjp

트리거를 해야 합니다.onChange수동으로 이벤트를 수행합니다.텍스트 입력 onChange가 듣기input이벤트입니다.

그래서 네 안에handleClick이벤트 트리거에 필요한 기능

handleClick () {
    this.setState({value: 'another random text'})
    var event = new Event('input', { bubbles: true });
    this.myinput.dispatchEvent(event);
  }

완전한 코드

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
    value: 'random text'
    }
  }
  handleChange (e) {
    console.log('handle change called')
  }
  handleClick () {
    this.setState({value: 'another random text'})
    var event = new Event('input', { bubbles: true });
    this.myinput.dispatchEvent(event);
  }
  render () {
    return (
      <div>
        <input readOnly value={this.state.value} onChange={(e) => {this.handleChange(e)}} ref={(input)=> this.myinput = input}/>
        <button onClick={this.handleClick.bind(this)}>Change Input</button>
      </div>
    )
  }
}

ReactDOM.render(<App />,  document.getElementById('app'))

코드펜

편집: 코멘트에서 @Samuel이 제안하는 바와 같이, 보다 간단한 방법은 전화하는 것입니다.handleChange부터handleClick네가 만약don't need to the event objecthandleChange맘에 들다

handleClick () {
    this.setState({value: 'another random text'})
    this.handleChange();
  }

이게 당신에게 필요한 것이고 당신에게 도움이 되길 바랍니다.

다른 해결책을 시도해 봤지만 소용이 없었어요.이는 React.js의 입력 로직이 변경되었기 때문입니다.상세한 것에 대하여는, https://hustle.bizongo.in/simulate-react-on-change-on-controlled-components-baa336920e04 를 참조해 주세요.

즉, 상태를 변경하여 입력값을 변경한 후 변경 이벤트를 디스패치하면 React는 setState와 이벤트를 모두 등록하고 중복 이벤트로 간주하여 삼킵니다.

솔루션은 입력 시 네이티브 값 설정기를 호출하는 것입니다(다음 코드의 setNativeValue 함수 참조).

코드 예시

import React, { Component } from 'react'
export class CustomInput extends Component {

    inputElement = null;
    
    // THIS FUNCTION CALLS NATIVE VALUE SETTER
    setNativeValue(element, value) {
        const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
        const prototype = Object.getPrototypeOf(element);
        const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;

        if (valueSetter && valueSetter !== prototypeValueSetter) {
            prototypeValueSetter.call(element, value);
        } else {
            valueSetter.call(element, value);
        }
    }


    constructor(props) {
        super(props);

        this.state = {
            inputValue: this.props.value,
        };
    }

    addToInput = (valueToAdd) => {
        this.setNativeValue(this.inputElement, +this.state.inputValue + +valueToAdd);
        this.inputElement.dispatchEvent(new Event('input', { bubbles: true }));
    };

    handleChange = e => {
        console.log(e);
        this.setState({ inputValue: e.target.value });
        this.props.onChange(e);
    };

    render() {
        return (
            <div>
                <button type="button" onClick={() => this.addToInput(-1)}>-</button>
                <input
                    readOnly
                    ref={input => { this.inputElement = input }}
                    name={this.props.name}
                    value={this.state.inputValue}
                    onChange={this.handleChange}></input>
                <button type="button" onClick={() => this.addToInput(+1)}>+</button>
            </div>
        )
    }
}

export default CustomInput

결과

여기에 이미지 설명 입력

이렇게 바꿔야 할 것 같아요.

<input value={this.state.value} onChange={(e) => {this.handleChange(e)}}/>

그것은 원칙적으로 와 같다.onClick={this.handleClick.bind(this)}당신이 버튼에서 했던 것처럼.

그래서 전화하고 싶으면handleChange()버튼을 클릭했을 때, 이하와 같이 합니다.

<button onClick={this.handleChange.bind(this)}>Change Input</button>

또는

handleClick () {
  this.setState({value: 'another random text'});
  this.handleChange();
}

기능 컴포넌트에서는 이 작업을 수행할 수 있습니다.input[type=number]

const MyInputComponent = () => {
    const [numberValue, setNumberValue] = useState(0);
    const numberInput = useRef(null);

    /**
    * Dispatch Event on Real DOM on Change
    */
    useEffect(() => {
        numberInput.current.dispatchEvent(
            new Event("change", {
                detail: {
                    newValue: numberValue,
                },
                bubbles: true,
                cancelable: true,
            })
        );
    }, [numberValue]);

    return (
        <>
            <input    
                type="number"            
                value={numberValue}             
                ref={numberInput}
                inputMode="numeric"
                onChange={(e) => setNumberValue(e.target.value)}
            />
        </>
    )
}

다른 답변은 렌더에서 직접 바인딩에 대해 언급하고 있기 때문에 몇 가지 사항을 추가하고 싶습니다.

함수를 렌더 또는 구성 요소의 다른 곳(컨스트럭터 제외)에서 직접 바인딩하지 않는 것이 좋습니다.모든 함수 바인딩에 대해 새로운 함수/개체가 webpack bundle js 파일에 생성되므로 번들 크기가 커집니다.컴포넌트는 setState 실행 시, 새로운 소품 수령 시 등 여러 가지 이유로 재렌더됩니다.this.forceUpdate()그 때문에, 렌더로 함수를 직접 바인드 하면, 항상 새로운 함수가 작성됩니다.대신 함수 바인딩은 항상 컨스트럭터에서 수행하고 필요한 경우 참조를 호출합니다.이렇게 하면 구성 요소당 생성자가 한 번만 호출되므로 새 함수가 한 번만 생성됩니다.

어떻게 해야 하는지는 다음과 같습니다.

constructor(props){
  super(props);
  this.state = {
    value: 'random text'
  }
  this.handleChange = this.handleChange.bind(this);
}

handleChange (e) {
  console.log('handle change called');
  this.setState({value: e.target.value});
}

<input value={this.state.value} onChange={this.handleChange}/>

화살표 기능을 사용할 수도 있지만 특정 경우에 구성 요소가 다시 렌더링될 때마다 화살표 기능도 새로 만듭니다.화살표 기능을 사용할 때와 사용하지 않아야 하는 시기를 알아야 합니다.화살표 기능을 사용하는 시기에 대한 자세한 설명은 여기에서 수락된 답변을 확인하십시오.

다음 4단계를 수행해야 합니다.

  1. 이벤트를 작성하다

    var event = new Event("change",{
        detail: {
            oldValue:yourValueVariable,
            newValue:!yourValueVariable
        },
        bubbles: true,
        cancelable: true
    });
    event.simulated = true;
    let tracker = this.yourComponentDomRef._valueTracker;
    if (tracker) {
        tracker.setValue(!yourValueVariable);
    }
    
  2. 값을 컴포넌트 dom에 바인드

    this.yourComponentDomRef.value = !yourValueVariable;
    
  3. 요소 변경을 바인드하여 onChange 함수를 반응시킵니다.

     this.yourComponentDomRef.onchange = (e)=>this.props.onChange(e);
    
  4. 디스패치 이벤트

    this.yourComponentDomRef.dispatchEvent(event);
    

yourComponentDomRef을 합니다.<div className="component-root-dom" ref={(dom)=>{this.yourComponentDomRef= dom}}>

React Native 및 Hooks를 사용한 접근법:

값이 변경되었는지 여부를 감시하는 새로운 값으로 TextInput을 랩하고 값이 변경되면 onChange 함수를 트리거할 수 있습니다.

import React, { useState, useEffect } from 'react';
import { View, TextInput as RNTextInput, Button } from 'react-native';

// New TextInput that triggers onChange when value changes.
// You can add more TextInput methods as props to it.
const TextInput = ({ onChange, value, placeholder }) => {

  // When value changes, you can do whatever you want or just to trigger the onChange function
  useEffect(() => {
    onChange(value);
  }, [value]);

  return (
    <RNTextInput
      onChange={onChange}
      value={value}
      placeholder={placeholder}
    />
  );
};

const Main = () => {

  const [myValue, setMyValue] = useState('');

  const handleChange = (value) => {
    setMyValue(value);
    console.log("Handling value");
  };

  const randomLetters = [...Array(15)].map(() => Math.random().toString(36)[2]).join('');

  return (
    <View>
      <TextInput
        placeholder="Write something here"
        onChange={handleChange}
        value={myValue}
      />
      <Button
        title='Change value with state'
        onPress={() => setMyValue(randomLetters)}
      />
    </View>
  );
};

export default Main;

handleChange by click 버튼을 트리거하고 싶으시다고요?

그러나 onChange 이벤트는 폼 요소 이벤트이므로 상태 값 수정은 onChange 이벤트를 트리거하지 않습니다.

저도 비슷한 요구가 있어서 결국 component Did Mount()를 사용하게 되었습니다.이것은 컴포넌트 클래스 컨스트럭터(소품에서 상태를 초기화할 수 있습니다.rex를 사용하여 exmpl로서)라고 불리는 컴포넌트 클래스 컨스트럭터(component Did Mount()를 사용하고 있습니다.

Inside componentDiMount에서는 일부 UI 애니메이션에 대해 handleChange 메서드를 호출하거나 필요한 컴포넌트 속성 업데이트를 수행할 수 있습니다.

예를 들어 입력 확인란 유형을 프로그래밍 방식으로 업데이트하는 데 문제가 있어서 onChange 핸들러가 컴포넌트 로드 시 실행되지 않았기 때문에 이 코드를 사용하게 되었습니다.

   componentDidMount() {

    // Update checked 
    const checkbox = document.querySelector('[type="checkbox"]');

    if (checkbox) 
      checkbox.checked = this.state.isChecked;
  }

상태가 구성 요소 클래스 생성자에서 먼저 업데이트된 후 일부 입력 구성 요소 동작을 업데이트하는 데 사용되었습니다.

에 "Sub " (가 있는 경우 이 를 사용해 보십시오.this.state.class.fee다음 코드를 사용하여 값을 전달할 수 있습니다.

this.setState({ class: Object.assign({}, this.state.class, { [element]: value }) }

언급URL : https://stackoverflow.com/questions/42550341/react-trigger-onchange-if-input-value-is-changing-by-state

반응형