자바 스크립트 변수를 재정의 할 수 없습니다.

JSON_Derulo

사용자가 검색 창에 입력 할 때 "자동 완성"권장 사항 목록을 표시하는 React 구성 요소가 있습니다. 사용자가 화살표 키와 Enter 키를 사용하여 목록을 탐색 할 수 있도록하려고합니다.

여기에 이미지 설명 입력

사용자가 처음으로 아래쪽 키를 누르면 포커스 변수가 1 씩 증가하고 HTML 포커스가 첫 번째 권장 사항으로 이동합니다. 다시 누르면 포커스 변수가 다시 1 씩 증가하고 HTML 포커스가 두 번째 권장 사항으로 이동하는 식입니다. 마찬가지로 사용자가 위쪽 키를 누르면 포커스가 1 씩 줄어들고 HTML 포커스가 이전 권장 사항으로 이동합니다. 또한 포커스 인덱스가 가능한 범위를 벗어나지 않도록하는 조치와 검색 바의 값이 변경 될 때 포커스 인덱스를 0으로 재설정하는 조치가 있습니다.

포커스 인덱스 값을 재정의 할 때 아래쪽 키를 사용할 때만 제대로 작동하고 위쪽 키를 누르면 재정의 이전의 이전 값 형식으로 변경된다는 이상한 오류가 발생합니다. 더 긴 검색을 입력하면 권장 사항 목록이 좁아지기 때문에 어떤 경우에는 포커스 인덱스가 범위를 벗어난 다음 충돌이 발생할 수 있습니다.

다음은 하나의 문자 만 검색 할 때 포커스 인덱스에 대한 콘솔 출력의 일부 스크린 샷입니다.

여기에 이미지 설명 입력 여기에 이미지 설명 입력

이제 검색 범위를 좁힌 다음 권장 사항을 탐색 할 때 어떤 일이 발생하는지 보여 드리겠습니다.

여기에 이미지 설명 입력 여기에 이미지 설명 입력

다음은 작동하는 코드 및 상자 링크입니다.

https://codesandbox.io/s/jolly-tu-7itsm?fontsize=14&hidenavigation=1&theme=dark

드류리스

발행물

좋아, 내가 예상했던 것과 똑같다. 당신은 동봉 한 일부 focus 독립적으로의 변이 된 "의 keyup"이벤트 핸들러에서 값 focus존재 각 주요 구성 요소 본문에주기를 렌더링 재설정 useEffect할 때 종속성 업데이트 후크를.

이 효과에 대한 코드 및 상자에 반응 린트 경고도 있습니다.

React Hook useEffect 내부에서 'focus'변수에 대한 할당은 각 렌더링 후 손실됩니다. 시간이 지남에 따라 값을 보존하려면 useRef 후크에 저장하고 '.current'속성에 변경 가능한 값을 유지하십시오.

해결책

  1. 모든 콜백 인스턴스와 후크가 동일한 안정된 값을 참조 할 수 있도록 "focus"값을 React ref에 저장합니다 .
  2. 또한 별도의 useEffect후크를 사용하여 "keyup"이벤트 리스너를 관리하고 구성 요소가 마운트 해제 될 때이를 제거하는 정리 기능을 사용하는 것이 좋습니다 . 이렇게하면 효과 콜백이 트리거 마다 새 리스너가 추가되는 것을 방지 할 수 있습니다 ( 코드가 렌더링 할 때마다 리스너를 추가했습니다 !! ).
  3. "autocomplete__container"직접 DOM 쿼리 및 조작이 React에서 안티 패턴으로 간주 되므로 컨테이너 를 참조하기 위해 React ref를 사용하는 것이 좋습니다 .

암호:

function App() {
  const [value, setValue] = useState("");
  const [items, setItems] = useState([]);
  const [query, setQuery] = useState([]);
  const [formSubmit, setFormSubmit] = useState(false);
  const [completions] = useAutocomplete(value, autocompleteValues);

  const autocompleteContainer = useRef(); // <-- ref to get DOMNode
  const focusRef = useRef(-1); // <-- ref to store stable focus value

  ...

  // Effect hook to manage keyup event handler and cleanup
  useEffect(() => {
    const handleKeypress = (event) => {
      if (event.keyCode === 38 && focusRef.current >= 1) { // <-- focus.current
        focusRef.current -= 1;
        autocompleteContainer.current.childNodes[focusRef.current].focus(); // <-- autocompleteContainer.current
      } else if (
        event.keyCode === 40 &&
        focusRef.current < autocompleteContainer.current.childElementCount - 1
      ) {
        focusRef.current += 1;
        autocompleteContainer.current.childNodes[focusRef.current].focus();
      } else if (
        event.keyCode === 13 &&
        document.activeElement.className !== "form-control"
      ) {
        setValue(document.activeElement.innerHTML);
        setQuery(document.activeElement.innerHTML);
        document.getElementsByClassName(
          "autocomplete__container"
        )[0].style.display = "none";
        setFormSubmit(true);
      }
    };

    window.addEventListener("keyup", handleKeypress); // <-- add listener

    return () => window.removeEventListener("keyup", handleKeypress); // <-- return cleanup function to remove listener
  }, []);

  // Effect hook to reset focus value when list updates
  useEffect(() => {
    focusRef.current = -1;
    console.log("focus reset", focusRef.current);
  }, [value, items]);

  return (
    <div className="App">
      <Form id="search__form" onSubmit={handleSubmit}>
        <Form.Group>
          <InputGroup className="mb-3">
            ...
            <div
              ref={autocompleteContainer} // <-- attach DOM ref here
              className="autocomplete__container"
            >
              {completions.map((val, index) => (
                <p
                  tabIndex={index + 10}
                  key={index}
                  onClick={() => updateInput({ val })}
                >
                  {val}
                </p>
              ))}
            </div>
          </InputGroup>
        </Form.Group>
      </Form>
      <p>{focusRef.current}</p>
    </div>
  );
}

재정의 할 수없는 자바 스크립트 변수 수정

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

자바 스크립트는 함수 내에서 전역 개체를 재정의 할 수 없습니다.

분류에서Dev

자바 스크립트에서 함수 외부의 변수를 사용할 수 없습니다.

분류에서Dev

Postman의 환경 변수를 통해 자바 스크립트 개체에 액세스 할 수 없습니다.

분류에서Dev

변수 값 자바 스크립트를 변경할 수 없습니다

분류에서Dev

Django-Django 양식의 ID를 자바 스크립트 변수에 전달할 수 없습니다.

분류에서Dev

자바 스크립트의 날짜 변수에 연도를 추가 할 수 없습니다.

분류에서Dev

자바 스크립트는 전역 변수를 호출 할 수 없습니다.

분류에서Dev

내 자바 스크립트를로드 할 수 없습니다.

분류에서Dev

내 프런트 엔드 자바 스크립트 파일이 다른 자바 스크립트 파일의 변수에 액세스 할 수 없습니다.

분류에서Dev

가치 변경시 자바 스크립트를 실행할 수 없습니다.

분류에서Dev

다른 클래스의 함수에서 자바 스크립트를 호출 할 수 없습니다.

분류에서Dev

사용자 정의 된 쉘 스크립트를 실행할 수 없습니다.

분류에서Dev

자바 스크립트 / 커피 스크립트 : 현재 컨텍스트의 변수를 콜백 함수로 전달할 수 있습니까?

분류에서Dev

자바 스크립트를 사용할 때 디자인을 조정할 수 없습니다.

분류에서Dev

자바 스크립트는 getElementsByTagName에서 정의되지 않은 메소드를 호출 할 수 없습니다.

분류에서Dev

자바 스크립트 : 정의되지 않은 메서드를 호출 할 수 없습니다.

분류에서Dev

자바 스크립트 : clearTimeout을 할 수 없습니다

분류에서Dev

자바 스크립트에서 변수 조합에 변수를 설정할 수 있습니까?

분류에서Dev

angular2 외부에서 변수 자바 스크립트 변수를 설정할 수 있습니까?

분류에서Dev

자바 스크립트는 xul의 oncommand를 사용할 수 없습니까?

분류에서Dev

자바 스크립트는 xul의 oncommand를 사용할 수 없습니까?

분류에서Dev

자바 스크립트의 변수가 변수를 생성 할 수 있습니까?

분류에서Dev

수동으로 변경할 수없는 기존 온 페이지 스크립트의 변수를 수정하는 자바 스크립트

분류에서Dev

사용자 지정 C # 웹 브라우저는 자바 스크립트를 지원할 수 없습니다.

분류에서Dev

내 Ajax URL에서 자바 스크립트 변수를 어떻게 정의 할 수 있습니까?

분류에서Dev

자바 스크립트 배열의 객체를 어떻게 재정렬 할 수 있습니까?

분류에서Dev

정지 자바 스크립트에서 이벤트를 제출할 수 없습니다

분류에서Dev

자바 스크립트의 문자열에서 \를 구문 분석 할 수 없습니다.

분류에서Dev

cefsharp는 자바 스크립트로 오디오를 재생할 수 없습니다.

Related 관련 기사

  1. 1

    자바 스크립트는 함수 내에서 전역 개체를 재정의 할 수 없습니다.

  2. 2

    자바 스크립트에서 함수 외부의 변수를 사용할 수 없습니다.

  3. 3

    Postman의 환경 변수를 통해 자바 스크립트 개체에 액세스 할 수 없습니다.

  4. 4

    변수 값 자바 스크립트를 변경할 수 없습니다

  5. 5

    Django-Django 양식의 ID를 자바 스크립트 변수에 전달할 수 없습니다.

  6. 6

    자바 스크립트의 날짜 변수에 연도를 추가 할 수 없습니다.

  7. 7

    자바 스크립트는 전역 변수를 호출 할 수 없습니다.

  8. 8

    내 자바 스크립트를로드 할 수 없습니다.

  9. 9

    내 프런트 엔드 자바 스크립트 파일이 다른 자바 스크립트 파일의 변수에 액세스 할 수 없습니다.

  10. 10

    가치 변경시 자바 스크립트를 실행할 수 없습니다.

  11. 11

    다른 클래스의 함수에서 자바 스크립트를 호출 할 수 없습니다.

  12. 12

    사용자 정의 된 쉘 스크립트를 실행할 수 없습니다.

  13. 13

    자바 스크립트 / 커피 스크립트 : 현재 컨텍스트의 변수를 콜백 함수로 전달할 수 있습니까?

  14. 14

    자바 스크립트를 사용할 때 디자인을 조정할 수 없습니다.

  15. 15

    자바 스크립트는 getElementsByTagName에서 정의되지 않은 메소드를 호출 할 수 없습니다.

  16. 16

    자바 스크립트 : 정의되지 않은 메서드를 호출 할 수 없습니다.

  17. 17

    자바 스크립트 : clearTimeout을 할 수 없습니다

  18. 18

    자바 스크립트에서 변수 조합에 변수를 설정할 수 있습니까?

  19. 19

    angular2 외부에서 변수 자바 스크립트 변수를 설정할 수 있습니까?

  20. 20

    자바 스크립트는 xul의 oncommand를 사용할 수 없습니까?

  21. 21

    자바 스크립트는 xul의 oncommand를 사용할 수 없습니까?

  22. 22

    자바 스크립트의 변수가 변수를 생성 할 수 있습니까?

  23. 23

    수동으로 변경할 수없는 기존 온 페이지 스크립트의 변수를 수정하는 자바 스크립트

  24. 24

    사용자 지정 C # 웹 브라우저는 자바 스크립트를 지원할 수 없습니다.

  25. 25

    내 Ajax URL에서 자바 스크립트 변수를 어떻게 정의 할 수 있습니까?

  26. 26

    자바 스크립트 배열의 객체를 어떻게 재정렬 할 수 있습니까?

  27. 27

    정지 자바 스크립트에서 이벤트를 제출할 수 없습니다

  28. 28

    자바 스크립트의 문자열에서 \를 구문 분석 할 수 없습니다.

  29. 29

    cefsharp는 자바 스크립트로 오디오를 재생할 수 없습니다.

뜨겁다태그

보관