React : useState가 업데이트되면 어떻게 동시에 업데이트되지 않을 수 있습니까?

GWorking

나는 반응 코드가 있습니다.

  • 설정 empty state
  • fills 상태
  • 이 상태가 채워지면 renders일부 이미지
  • 이 이미지는 onLoad이벤트 를 트리거합니다.
  • 이 onLoad 이벤트는 다음 호출 functionreads초기를state
  • 하지만이 상태는 empty

어떻게 그럴 수 있습니까? 함수가 호출되면 상태가 더 이상 비어 있지 않음을 의미합니다.

https://codesandbox.io/s/usestate-strange-things-9rydu

코드

import React, { useRef, useState, useEffect } from "react";
import styled from "@emotion/styled";

const useMyHook = (virtual_structure, setVirtual_structure) => {
  useEffect(() => {
    console.log("virtual_structure is updated!");
    console.log(virtual_structure);
    console.log("____virtual_structure is updated!");
  }, [virtual_structure]);

  const refs = useRef([]);

  const createStructure = () => {
    console.log("virtual_structure, is it empty?");
    console.log(virtual_structure);
  };

  useEffect(() => {
    createStructure();
  }, []);

  const assignRef = r =>
    r && (refs.current.includes(r) || refs.current.push(r));

  return [assignRef, createStructure];
};

export default function App() {
  const [virtual_structure, setVirtual_structure] = useState([]);

  const [assignRef, updateGrid] = useMyHook(
    virtual_structure,
    setVirtual_structure
  );

  useEffect(() => {
    const temp_structure = Array.from({ length: 4 }, () => ({
      height: 0,
      cells: []
    }));
    temp_structure[0].cells = Array.from({ length: 10 }, () => {
      const rand = Math.random();
      const r = rand > 0.1 ? parseInt(500 * rand) : parseInt(500 * 0.1);
      return {
        height: "",
        el: (
          <div ref={assignRef}>
            <Image
              alt=""
              onload={updateGrid}
              num=""
              src={`https://picsum.photos/200/${r}`}
            />
          </div>
        )
      };
    });

    setVirtual_structure(temp_structure);
  }, []);

  return (
    <Container>
      {virtual_structure.map((col, i) => (
        <div key={`col${i}`}>
          {col.cells && col.cells.map((cell, j) => <>{cell.el}</>)}
        </div>
      ))}
    </Container>
  );
}

const Image = ({ alt, onload, num, src }) => (
  <>
    <Label>{num}</Label>
    <Img src={src} alt={alt} onLoad={onload} />
  </>
);

const Img = styled.img`
  border: 1px solid #000;
  height: min-content;
  margin: 0;
  padding: 0;
`;
const Label = styled.div`
  position: absolute;
`;

const Container = styled.div`
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  background: #ccc;
  align-content: center;

  div {
    flex: 1;

    div {
      color: #fff;
      font-weight: 700;
      font-size: 32px;
      margin: 4px;
    }
  }
`;

그리고 console.log

virtual_structure is updated!
index.js:27 Array(0)length: 0__proto__: Array(0)
index.js:27 ____virtual_structure is updated!
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure is updated!
index.js:27 Array(4)0: {height: 0, cells: Array(10)}1: {height: 0, cells: Array(0)}2: {height: 0, cells: Array(0)}3: {height: 0, cells: Array(0)}length: 4__proto__: Array(0)
index.js:27 ____virtual_structure is updated!
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)length: 0__proto__: Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 []length: 0__proto__: Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 []
GWorking

@ Dennis-vash 답변에서 말했듯이 "클로저"는 useState범위 함수 내에서 변수를 고정하므로이 함수는이 변수의 현재 (업데이트 된) 값을 볼 수 없습니다.

해결 방법은 논리를 실행하는 함수를 호출하는 대신 항상 상태를 업데이트하는 함수를 호출 한 다음이 상태를 사용하여 함수를 트리거 할 수 있다는 것입니다 (이제 함수 대신 useEffect 사용).


누군가이 문제를 해결하기 위해 더 나은 대안을 제안하고 싶은 경우를 대비하여 며칠 동안 질문을 열어 두겠습니다 (?)


코드

https://codesandbox.io/s/usestate-strange-things-tneue

import React, { useRef, useState, useEffect } from "react";
import styled from "@emotion/styled";

const useMyHook = (virtual_structure, setVirtual_structure, updateGrid) => {
  const refs = useRef([]);

  useEffect(() => {
    console.log("virtual_structure, is it empty?");
    console.log(virtual_structure);
  }, [updateGrid, virtual_structure]);

  const assignRef = r =>
    r && (refs.current.includes(r) || refs.current.push(r));

  return [assignRef];
};

export default function App() {
  const [virtual_structure, setVirtual_structure] = useState([]);
  const [updateGrid, setUpdateGrid] = useState();

  const [assignRef] = useMyHook(
    virtual_structure,
    setVirtual_structure,
    updateGrid
  );

  const update = async () => setUpdateGrid(updateGrid + 1);

  useEffect(() => {
    const temp_structure = Array.from({ length: 4 }, () => ({
      height: 0,
      cells: []
    }));
    temp_structure[0].cells = Array.from({ length: 10 }, () => {
      const rand = Math.random();
      const r = rand > 0.1 ? parseInt(500 * rand) : parseInt(500 * 0.1);
      return {
        height: "",
        el: (
          <div ref={assignRef}>
            <Image
              alt=""
              onload={update}
              num=""
              src={`https://picsum.photos/200/${r}`}
            />
          </div>
        )
      };
    });

    setVirtual_structure(temp_structure);
  }, []);

  return (
    <Container>
      {virtual_structure.map((col, i) => (
        <div key={`col${i}`}>
          {col.cells &&
            col.cells.map((cell, j) => (
              <React.Fragment key={`cell${j}`}>{cell.el}</React.Fragment>
            ))}
        </div>
      ))}
    </Container>
  );
}

const Image = ({ alt, onload, num, src }) => (
  <>
    <Label>{num}</Label>
    <Img src={src} alt={alt} onLoad={onload} />
  </>
);

const Img = styled.img`
  border: 1px solid #000;
  height: min-content;
  margin: 0;
  padding: 0;
`;
const Label = styled.div`
  position: absolute;
`;

const Container = styled.div`
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  background: #ccc;
  align-content: center;

  div {
    flex: 1;

    div {
      color: #fff;
      font-weight: 700;
      font-size: 32px;
      margin: 4px;
    }
  }
`;

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

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

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Rails 5.2-번들 업데이트로 업데이트가되지 않을 때 Rake Gem을 어떻게 업데이트 할 수 있나요?

분류에서Dev

네트워크 (프로그레시브 웹 앱)에서 사용 가능한 업데이트가 있으면 캐시가 업데이트되거나 업데이트되지 않습니다. 그렇다면 어떻게?

분류에서Dev

중복 키 업데이트시 자동 증가 ID가 업데이트되지 않도록하려면 어떻게해야합니까?

분류에서Dev

Bing 바가 Windows 업데이트에 표시되지 않도록하려면 어떻게해야합니까?

분류에서Dev

ionic 3에서 데이터가 변경되면 어떻게 자동으로 변수 값을 업데이트합니까?

분류에서Dev

시스템 이미지 백업을 업데이트 할 수 있습니까? 그렇다면 어떻게?

분류에서Dev

Windows가 시작될 때마다 레지스트리 값을 어떻게 업데이트 할 수 있습니까?

분류에서Dev

다른 필수 필드가 비어 있으면 InputText가 업데이트되지 않습니까?

분류에서Dev

자동 업데이트 후 Windows가 재부팅되지 않도록하려면 어떻게해야합니까?

분류에서Dev

우분투 업데이트가 잘못되어 PC가 부팅되지 않습니다. 어떻게 수리 할 수 있습니까?

분류에서Dev

사용자에게 팝업 후 범위 변수가 업데이트되지만 특정 위치에는 업데이트되지 않습니다.

분류에서Dev

함수가 호출되는 방법에 따라 React 후크 (특히 useState)를 업데이트하지 않습니까?

분류에서Dev

React 후크를 사용하여 소품을 통해 자식에게 전달되는 객체를 어떻게 업데이트 할 수 있습니까?

분류에서Dev

코드를 실행하면 하나의 워크 시트 만 업데이트됩니다 (예 : Apple). 다른 3 개의 워크 시트는 업데이트되지 않습니다. 어떻게 해결할 수 있습니까?

분류에서Dev

커널 업데이트 후 우분투 14.04가 작동하지 않습니다. 우분투 시스템을 어떻게 저장할 수 있습니까?

분류에서Dev

행이 없거나 데이터가 업데이트로 변경되지 않았는지 어떻게 알 수 있습니까?

분류에서Dev

React useState가 깨 졌나요? 상태가 올바르게 업데이트되지 않았습니다.

분류에서Dev

양식이 계속 업데이트되면 재설정되는 자동 저장을 어떻게 구현할 수 있습니까?

분류에서Dev

Mobx에서 Window Resize 이벤트를 수신하면 React Konva에서 Stage 구성 요소의 너비 및 높이가 업데이트되지 않습니다.

분류에서Dev

Windows 10 1 주년 업데이트에서 Synaptics 확장을 어떻게 되 찾을 수 있습니까?

분류에서Dev

listview 항목 평가 필드가 updatePanel에서 어떻게 업데이트되지 않습니까?

분류에서Dev

이 자바에서 특정 시간 간격으로 업데이트되지 때 어떻게 null로 변수의 값을 타임 아웃 할 수 있습니까?

분류에서Dev

React Hooks : useState를 사용하여 상태를 업데이트해도 상태가 즉시 업데이트되지 않습니다.

분류에서Dev

WebSocket과 함께 useState를 반응 시키면 배열이 올바르게 업데이트되지 않습니다.

분류에서Dev

React가 상태 변경에 대해 업데이트되지 않습니까?

분류에서Dev

이 루프에서 업데이트되지 않는 변수를 어떻게 생성합니까?

분류에서Dev

UITableView에서 행을 선택하면 변수가 업데이트되지 않습니다.

분류에서Dev

내 매크로에 의해 이전 데이터가 업데이트되지 않도록하려면 어떻게합니까?

분류에서Dev

때때로 slickgrid가 업데이트되면 업데이트가 표시되지 않습니다.

Related 관련 기사

  1. 1

    Rails 5.2-번들 업데이트로 업데이트가되지 않을 때 Rake Gem을 어떻게 업데이트 할 수 있나요?

  2. 2

    네트워크 (프로그레시브 웹 앱)에서 사용 가능한 업데이트가 있으면 캐시가 업데이트되거나 업데이트되지 않습니다. 그렇다면 어떻게?

  3. 3

    중복 키 업데이트시 자동 증가 ID가 업데이트되지 않도록하려면 어떻게해야합니까?

  4. 4

    Bing 바가 Windows 업데이트에 표시되지 않도록하려면 어떻게해야합니까?

  5. 5

    ionic 3에서 데이터가 변경되면 어떻게 자동으로 변수 값을 업데이트합니까?

  6. 6

    시스템 이미지 백업을 업데이트 할 수 있습니까? 그렇다면 어떻게?

  7. 7

    Windows가 시작될 때마다 레지스트리 값을 어떻게 업데이트 할 수 있습니까?

  8. 8

    다른 필수 필드가 비어 있으면 InputText가 업데이트되지 않습니까?

  9. 9

    자동 업데이트 후 Windows가 재부팅되지 않도록하려면 어떻게해야합니까?

  10. 10

    우분투 업데이트가 잘못되어 PC가 부팅되지 않습니다. 어떻게 수리 할 수 있습니까?

  11. 11

    사용자에게 팝업 후 범위 변수가 업데이트되지만 특정 위치에는 업데이트되지 않습니다.

  12. 12

    함수가 호출되는 방법에 따라 React 후크 (특히 useState)를 업데이트하지 않습니까?

  13. 13

    React 후크를 사용하여 소품을 통해 자식에게 전달되는 객체를 어떻게 업데이트 할 수 있습니까?

  14. 14

    코드를 실행하면 하나의 워크 시트 만 업데이트됩니다 (예 : Apple). 다른 3 개의 워크 시트는 업데이트되지 않습니다. 어떻게 해결할 수 있습니까?

  15. 15

    커널 업데이트 후 우분투 14.04가 작동하지 않습니다. 우분투 시스템을 어떻게 저장할 수 있습니까?

  16. 16

    행이 없거나 데이터가 업데이트로 변경되지 않았는지 어떻게 알 수 있습니까?

  17. 17

    React useState가 깨 졌나요? 상태가 올바르게 업데이트되지 않았습니다.

  18. 18

    양식이 계속 업데이트되면 재설정되는 자동 저장을 어떻게 구현할 수 있습니까?

  19. 19

    Mobx에서 Window Resize 이벤트를 수신하면 React Konva에서 Stage 구성 요소의 너비 및 높이가 업데이트되지 않습니다.

  20. 20

    Windows 10 1 주년 업데이트에서 Synaptics 확장을 어떻게 되 찾을 수 있습니까?

  21. 21

    listview 항목 평가 필드가 updatePanel에서 어떻게 업데이트되지 않습니까?

  22. 22

    이 자바에서 특정 시간 간격으로 업데이트되지 때 어떻게 null로 변수의 값을 타임 아웃 할 수 있습니까?

  23. 23

    React Hooks : useState를 사용하여 상태를 업데이트해도 상태가 즉시 업데이트되지 않습니다.

  24. 24

    WebSocket과 함께 useState를 반응 시키면 배열이 올바르게 업데이트되지 않습니다.

  25. 25

    React가 상태 변경에 대해 업데이트되지 않습니까?

  26. 26

    이 루프에서 업데이트되지 않는 변수를 어떻게 생성합니까?

  27. 27

    UITableView에서 행을 선택하면 변수가 업데이트되지 않습니다.

  28. 28

    내 매크로에 의해 이전 데이터가 업데이트되지 않도록하려면 어떻게합니까?

  29. 29

    때때로 slickgrid가 업데이트되면 업데이트가 표시되지 않습니다.

뜨겁다태그

보관