useState 갈고리를 사용하여 상태 업데이트

20654 단어 computersciencereact

모티프


useState 갈고리는 임시 구성 요소 상태를 제공하는 편리한 방법입니다.useState 갈고리를 호출해서 단추나 다른 시각 구성 요소의 상호작용을 증가시키는 것은 매우 흔한 일이다.useState 갈고리를 사용할 때 세 가지 주요 문제가 있습니다.
  • 국가가 필요합니까?
  • 상태가 어셈블리 트리의 올바른 수준에 있습니까?
  • 상태 업데이트가 정확합니까?
  • 앞의 두 가지 질문에 대답할 때 상태 관리 솔루션을 선택할 것인지, 조합을 사용할 것인지, 계승할 것인지를 고려할 수 있다.Composition vs Inheritance,Lifting State upThinking in React에서 그것들에 대해 토론을 진행했다.나는 정확한 업데이트 상태에 대한 정보를 공유하고 싶다. (내가 실현하고 있는 새로운 특성에서 나는 이 점을 하지 못했다.)

    조우


    다음 단계에서 완성한 보조 항목의 테스트 목록을 표시하기 위해 검색 + 정렬 기능을 추가했습니다.js.검색 입력과 정렬 옵션을 추적하기 위해서, 나는useState 갈고리 두 개를 사용했다.나는 아래의 관련 코드를 추출했는데, 간결하게 보기 위해 스타일과 관련된 클래스와 구성 요소가 생략되었다.
    주요 사항:
  • QuizList 구성 요소 수신 퀴즈 목록
  • query 추적 검색 입력
  • sortBy 추적 정렬 옵션
  • filteredQuizzes 표시할 테스트의 조종 사본을 기록한다
  • const QuizList = ({ quizzes }: { quizzes: Quiz[] }): JSX.Element => {
      const [query, setQuery] = useState('')
      const [sortBy, setSortBy] = useState('title')
      const [filteredQuizzes, setFilteredQuizzes] = useState<Quiz[]>([])
      useEffect(() => {
          let result = quizzes
          if (sortBy === 'title') {
            result.sort((a, b) => a.title.localeCompare(b.title))
          } else {
            result.sort((a, b) => a.week - b.week)
          }
          if (query.trim() === '') {
            setFilteredQuizzes(result)
          } else {
            setFilteredQuizzes(
              result.filter((quiz) => quiz.title.toLowerCase().includes(query.toLowerCase()))
            )
          }
        }
      }, [query, quizzes, sortBy])
      return (
          <div>
            <Search query={query} setQuery={setQuery} />
            <RadioGroup onChange={setSortBy} value={sortBy}>
              <Stack direction="row">
                <span>Sort by:</span>
                <Radio value="title">Title</Radio>
                <Radio value="week">Week</Radio>
              </Stack>
            </RadioGroup>
            <div>
                {filteredQuizzes.map((quiz) => {
                  return <QuizItemCard key={quiz.id} quiz={quiz} />
                })}
            </div>
          </div>
      )
    
    
    이것이 바로 그의 모습이다.

    나는 몇 번이나 불변성 원칙을 어기고 let 성명 변수가 아닌 const 성명 변수로 나의 코드를 시작하기로 결정했는데, 그들은 항상 숨겨진 오류로 나를 놀라게 했다.
    위의 코드는 유효한 것 같지만, '제목' 순서와 '주' 순서의 옵션 사이를 전환할 때 이상한 지연이 발생했습니다.사실 순서가 틀린 것 같다.
    코드의 논리는 다음과 같습니다.
  • 정렬 옵션을 검사하고 제목별로 정렬하면 테스트 목록을 정렬하고 문제를 비교합니다.그렇지 않으면 각 퀴즈의 주 속성별로 목록을 정렬합니다
  • .
  • 그리고 검색 입력을 검사하고 검색 입력만 저장
  • 나는 이러한 불일치와 지연된 정렬 행위가 테스트 목록의 돌연변이와 setFilteredQuizzes의 오류 사용으로 인한 것이라고 의심한다.공교롭게도, 나는 이번 주에 쓴 그 문장이 정부의 React와 관련이 있을 계획이다.js FAQ와 Component State에 관한 부분을 읽어서 상태 업데이트를 어떻게 복구하는지 알게 되었습니다.

    수리하다.


    FAQ의 구성 요소 상태 부분에서 설명한 바와 같이 setState 작업은 즉시 호출되지 않으며 잘못 사용하면 의외의 결과를 초래할 수 있습니다.문서의 예제 코드 세그먼트를 직접 참조하려면 다음과 같이 하십시오.
    incrementCount() {
      this.setState((state) => {
        // Important: read `state` instead of `this.state` when updating.
        return {count: state.count + 1}
      });
    }
    
    handleSomething() {
      // Let's say `this.state.count` starts at 0.
      this.incrementCount();
      this.incrementCount();
      this.incrementCount();
    
      // If you read `this.state.count` now, it would still be 0.
      // But when React re-renders the component, it will be 3.
    }
    
    상술한 사실 때문에 setState 조작은 업데이트를 받아들일 수 있는 상태도 있고 업데이트 함수도 받아들일 수 있다. 이 함수는 이전의 상태를 받아들이고 업데이트의 상태를 되돌려준다.
    따라서, 나의 해결 방안은 매우 간단하다.spread 조작부호를 사용하여 목록을 복사하고, 목록을 정렬하고, 업데이트 함수에서 그것을 되돌려준다.업데이트 기능에서 업데이트를 진행하면 인용filteredQuizzes이 언제든지 최신 업데이트 목록을 사용할 수 있습니다.다른 대체 해결 방안은 정렬 단추를 업데이트하는 이벤트 처리 프로그램 filteredQuizzes 을 포함하고 정렬 상태를 추적하는 것이 아닙니다.
    고정 버전은 다음과 같습니다.

    코드는 다음과 같습니다.
    const QuizList = ({ quizzes }: { quizzes: Quiz[] }): JSX.Element => {
      const [query, setQuery] = useState('')
      const [sortBy, setSortBy] = useState('title')
      const [filteredQuizzes, setFilteredQuizzes] = useState<Quiz[]>([])
      useEffect(() => {
        if (sortBy === 'title') {
          setFilteredQuizzes(() => [...quizzes].sort((a, b) => a.title.localeCompare(b.title)))
        } else {
          setFilteredQuizzes(() => [...quizzes].sort((a, b) => a.week - b.week))
          )
        }
        if (query.trim() === '') {
          setFilteredQuizzes((filteredQuizzes) => filteredQuizzes)
        } else {
          setFilteredQuizzes((filteredQuizzes) =>
            filteredQuizzes.filter((quiz) => quiz.title.toLowerCase().includes(query.toLowerCase()))
          )
        }
      }, [query, quizzes, sortBy])
      return (
        <div>
            <Search query={query} setQuery={setQuery} />
            <RadioGroup onChange={setSortBy} value={sortBy}>
              <Stack direction="row">
                <span>Sort by:</span>
                <Radio value="title">Title</Radio>
                <Radio value="week">Week</Radio>
              </Stack>
            </RadioGroup>
            <div>
                {filteredQuizzes.map((quiz) => {
                  return <QuizItemCard key={quiz.id} quiz={quiz} />
                })}
            </div>
        </div>
      )
    
    

    결론


    게으른 사람으로서 몇 가지 실험을 한 후에, 나는 상술한 오류에 대한 최초의 반응은 정렬 옵션을 삭제하고, 곧 다가올 테스트만 정렬하는 것이다.제가 이 글을 쓰기 시작했고 Kent C.Dodds의 계발을 받아 React FAQ를 읽었기 때문에 저는 이 작은 문제에 대해 더 많은 시간을 들였습니다.
    내가 짐작컨대 이 이야기의 우의는 다음과 같다.
  • 항상 지름길로 가지 마라
  • 문제를 재고
  • 글 쓰기 시작😂
  • 좋은 웹페이지 즐겨찾기