programing

reactJs가 event.persist()가 있는 이벤트에서 상태를 설정할 수 없습니다.

bestprogram 2023. 3. 28. 22:46

reactJs가 event.persist()가 있는 이벤트에서 상태를 설정할 수 없습니다.

이벤트에서 얻은 상태 필드를 설정해야 하는데 함수를 전달해도 설정되지 않습니다.컴포넌트 및 방법은 다음과 같습니다.

constructor(props: SomeProps, context: any) {
  super(props, context);
  this.state = {
    isFiltering: props.isFiltering,
    anchor: "",
  };
}

private toggleFilter = (event: any) => {
  event.persist()
  this.setState(prevState => ({
    isFiltering: !prevState.isFiltering,
    anchor: event.currentTarget // does not work, it's null
  }));
}

삭제하면event.persist()다음의 에러가 표시됩니다.

이 가상 이벤트는 성능상의 이유로 재사용됩니다.이 경우 메서드에 액세스하고 있는 것입니다.currentTarget공개/검증된 모의 이벤트에 대한 것입니다.이것은 no-op 기능입니다.원래 모의 이벤트를 보관해야 할 경우 event.persist()를 사용합니다.상세한 것에 대하여는, https://facebook.github.io/react/docs/events.html#event-pooling 를 참조해 주세요.

어떠한 이유로, 다음의 코드가 기능합니다.

private toggleFilter = (event: any) => {
  this.setState({anchor:event.currentTarget}) // works fine
  this.setState(prevState => ({
    isFiltering: !prevState.isFiltering,
  }));
}

위는 왜 동작하는데 사용했을 때는 동작하지 않는가?this.setState(prevState=> ...)?

그게 예상된 행동이야, 왜냐면event.persist()을 의미하는 것은 아니다currentTarget는 무효가 되지 않습니다.사실 무효가 되어야 합니다.이것은 브라우저의 네이티브 실장에 준거하고 있습니다.

즉, 비동기 방식으로 currentTarget에 액세스하려면 응답에서와 같이 변수에 캐시해야 합니다.


React의 핵심 개발자 중 한 명인 Sophie Alpert를 예로 들겠습니다.

currentTarget은 이벤트가 버블화됨에 따라 변화합니다.이벤트를 수신하는 요소에 이벤트 핸들러가 있고 그 상위 요소에 이벤트 핸들러가 있는 경우 currentTarget에 다른 값이 표시됩니다.IIRC를 무효로 하는 것은 네이티브 이벤트에서 일어나는 일과 일치합니다.그렇지 않은 경우 알려주시면 여기서의 행동을 재고하겠습니다.

공식 React 저장소에서 논의의 출처와 제가 조금 건드린 Sophie가 제공한 다음 토막을 확인하십시오.

var savedEvent;
var savedTarget;

divb.addEventListener('click', function(e) {
  savedEvent = e;
  savedTarget = e.currentTarget;
  setTimeout(function() {
    console.log('b: currentTarget is now ' + e.currentTarget);
  }, 0);
}, false);

diva.addEventListener('click', function(e) {
  console.log('same event object? ' + (e === savedEvent));
  console.log('same target? ' + (savedTarget === e.currentTarget));
  setTimeout(function() {
    console.log('a: currentTarget is now ' + e.currentTarget);
  }, 0);
}, false);
div {
  padding: 50px;
  background: rgba(0,0,0,0.5);
  color: white;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>

  <div id="diva"><div id="divb"> Click me and see output! </div></div>
  
</body>
</html>

@30dot님의 코멘트로 저는 유효한 솔루션을 얻었습니다.

setState가 "async"이기 때문에 setState에 전달된 함수가 실행될 때(그리고 이벤트에 액세스 할 때)에는 이벤트가 없어지기 때문이라고 생각합니다.두 번째 버전에서는 이벤트가 즉시 액세스되고 해당 currentTarget이 setState로 전달됩니다.

그래서 저장했습니다.event.currentTargetReactJs 이벤트 풀링에 설명된 대로 변수를 사용하여

이렇게 생겼고 효과가 있습니다.

private toggleFilter = (event: any) => {
        let target = event.currentTarget;   
        this.setState((prevState) => ({
            isFiltering: !prevState.isFiltering,
            anchor: target
        }));
    }

하지만 이것은 왜 그런지 설명해주지 않는다.event.persist()동작하지 않습니다.설명이 되는 답변을 받아들이겠습니다.

이 문제를 해결하려면 handleSubmit of form을 호출하기 전에 event.persist()를 호출하고 handleSubmit() 정의에 로직을 기록합니다.예를 들어,

<form id="add_exp_form" onSubmit={(event) => {event.persist();this.handleSubmit(event)}}>

handleSubmit(event){
    // use event.currentTarget - It will be visible here
}

에서는 const를 해야 합니다.event.preventDefault() ★★★★★★★★★★★★★★★★★」event.prevent()

예:

updateSpecs1 = (event) => { 
    event.preventDefault()

컴포넌트를 동적으로 채울 때 비슷한 경고 메시지가 뜨는데, 이를 해결하려면 기능을 화살표 기능으로 감싸야 했습니다.

송신원:

{ text: "Delete item", onClick: deleteItem },

수신인:

{ text: "Delete item", onClick: (id) => deleteItem(id) },

이 문제에 대한 좋은 설명과 두 가지 다른 해결책이 있습니다. 이 링크에서 확인할 수 있습니다.

이렇게 큐어 기능을 사용하여 처리할 수 있습니다.

const persistEvent = (fun: any) => (e: any) => {
e.persist();
fun(e);
};

이제 기능을 다음과 같이 쓸 수 있습니다.

persistEvent(toggleFilter);

다음과 같습니다.

const persistEvent = (fun: any) => (e: any) => {
    e.persist();
    fun(e);
    };

const delayedFunctionality = (e) => {
  setTimeout(()=> {
     console.log(e.target.value)
  },500
}

<input onChange={persistEvent(delayedFunctionality)} />

언급URL : https://stackoverflow.com/questions/42089795/reactjs-cant-set-state-from-an-event-with-event-persist