React 갈고리를 사용하여 부울 상태 오른쪽 업데이트
25300 단어 reactwebdevbeginnersjavascript
const MyComponent = (props) => {
const [isToggled, setIsToggled] = React.useState(false);
const toggle = React.useCallback(() => setIsToggled(!isToggled));
return ...;
};
부울 상태와 전환 방법을 만드는 것은 매우 흔히 볼 수 있는 용례이다.자선망은 기능적으로 100% 정확하다.하지만 성능 면에서는 더 좋을 수 있다.어떻게 개선하는지 봅시다.그럼 왜?
첫 번째 일은 우선이다. useCallback
이 실현에서 아무것도 하지 않는다.의존 관계 수조를 두 번째 매개 변수로 전달하지 않는 한 useCallback
은 리셋에 대한 동일한 참조를 유지하는 것이 아니라 다음 리셋 성명과 같다.
const toggle = () => setIsToggled(!isToggled);
그 밖에 현재의 실현은 가난한 의존항 규칙을 위반했다. 함수에서 인용한 모든 값도 의존항 수조에 나타나야 한다.이것은 리셋 중의 값이 항상 최신이고 이와 관련된 어떠한 오류도 피하기 위해서이다.
우리 실천에서 이 두 가지가 어떻게 성능에 영향을 미치는지 봅시다.우선 간단한 RendersCounter
구성 요소를 만듭니다. 이 구성 요소는 단일한 onClick
도구를 사용합니다.그러면 어셈블리가 렌더링되는 횟수가 계산됩니다.
import React from 'react';
const RendersCounter = ({ onClick }) => {
const rendersCountRef = React.useRef(0);
rendersCountRef.current += 1;
return (
<div>
<span>
RendersCounter rendered <b>{rendersCountRef.current}</b> time(s)
</span>
<button style={{ marginLeft: '10px' }} onClick={onClick}>
toggle
</button>
</div>
)
};
export default React.memo(RendersCounter);
RendersCounter
용React.memo
으로 소포하십시오.우리가 진행할 최적화는 하위 구성 요소가 순수한 구성 요소일 때만 유효하다. 이것은 React.PureComponent
의 실례이고 React.memo
로 포장된 기능 구성 요소이거나 shouldComponentUpdate
또는 다른 방식으로 인용 등식 렌더링 최적화를 한다.서브어셈블리에 대해 이러한 작업을 수행하지 않은 경우 리셋을 수행하는 방식에 관계없이 상위 어셈블리를 다시 표시할 때마다 다시 표시됩니다.
이제 이 구성 요소를 사용해서 의존항을 useCallback
에게 전달하지 않으면 무슨 일이 일어날지 봅시다.나는 두 개의 독립된 상태 처리 프로그램을 만들 것이다. 하나는 볼 상태이고, 다른 하나는 무작위 수를 저장하는 데 쓰인다.
const BasicBooleanState = () => {
const [isToggled, setIsToggled] = React.useState(false);
const toggle = React.useCallback(() => setIsToggled(!isToggled));
const [randomNumber, setRandomNumber] = React.useState(Math.random());
const generateRandomNumber = React.useCallback(
() => setRandomNumber(Math.random()),
[],
);
return (
<div>
<div>
Current random number is <b>{randomNumber}</b>
<button style={{ marginLeft: '10px' }} onClick={generateRandomNumber}>
regenerate
</button>
</div>
<div>
Boolean is set to <b>{String(isToggled)}</b>.
</div>
<RendersCounter onClick={toggle} />
</div>
);
}
RendersCounter
부울 상태가 변경되지 않더라도 다시 렌더링!
앞에서 말한 바와 같이 toggle
의 현재useCallback
는 일반적인 화살표 함수 성명에 해당한다.렌더링할 때마다 다시 만들어지기 때문에 RendersCounter
다른 onClick
도구를 참조하여 필요하지 않을 때 다시 렌더링할 수 있습니다.
Try it yourself
부족한 의존 항목 복구
React 문서 설명:
Every value referenced inside the function should also appear in the dependencies array
이 규칙을 따르지 않으면 콜백에 오래된 값이 나타날 수 있습니다.toggle
콜백에는 isToggled
및 setIsToggled
두 개의 외부 값이 사용됩니다.그것들을 useCallback
의 의존 관계 그룹에 넣읍시다.
const BasicBooleanState = () => {
const [isToggled, setIsToggled] = React.useState(false);
// here we added [isToggled, setIsToggled] as a second parameter
const toggle = React.useCallback(
() => setIsToggled(!isToggled),
[isToggled, setIsToggled],
);
const [randomNumber, setRandomNumber] = React.useState(Math.random());
const generateRandomNumber = React.useCallback(
() => setRandomNumber(Math.random()),
[],
);
return (
<div>
<div>
Current random number is <b>{randomNumber}</b>
<button style={{ marginLeft: '10px' }} onClick={generateRandomNumber}>
regenerate
</button>
</div>
<div>
Boolean is set to <b>{String(isToggled)}</b>.
</div>
<RendersCounter onClick={toggle} />
</div>
);
}
현재 RendersCounter
랜덤 수 변경 시 다시 렌더링되지 않습니다!우리는 리셋이 isToggled
또는 setIsToggled
변경될 때만 업데이트된다고 말했기 때문에 isToggled
변경이 없으면 인용에 있어서 같다.
그러나 RendersCounter
에서 부울 상태를 전환하면 다시 렌더링됩니다.isToggled
에 변화가 생겼고 useCallback
의존항수조의 일부이기 때문에 의미가 있다.
Try it yourself
리셋 최적화
리셋 toggle
문제를 해결하기 위해서는 직접적인 의존 isToggled
을 피하는 방법이 필요하지만, 리셋에는 실제 값이 있습니다.다음은 useRef
지원 서비스입니다.우리는 인용을 한 번만 만들고 isToggled
변경할 때 그 값을 업데이트할 수 있습니다.그리고 우리는 의존항수 그룹의 인용으로 isToggled
대체하고 그 자체를 리셋합니다. 이렇게!
사용자 정의 갈고리를 만듭니다. 현재 볼 상태와 전환 방법을 되돌려줍니다. 이 방법은 볼 값을 변경하고 있으며 영원히 다시 만들어지지 않습니다.
// it might be a project-level reusable hook
const useToggle = (initialState) => {
const [isToggled, setIsToggled] = React.useState(initialState);
const isToggledRef = React.useRef(isToggled);
// put [isToggledRef, setIsToggled] into the useCallback's dependencies array
// these values never change so the calllback is not going to be ever re-created
const toggle = React.useCallback(
() => setIsToggled(!isToggledRef.current),
[isToggledRef, setIsToggled],
);
// keep the value in isToggledRef actual
// when isToggled changes, isToggledRef is updated accordingly
React.useEffect(
() => {
isToggledRef.current = isToggled;
},
[isToggled],
);
return [isToggled, toggle];
}
우리는 isToggled
대신 isToggledRef
리셋을 만들기 위해 toggle
을 사용합니다.isToggledRef
및 setIsToggled
은 한 번만 생성됩니다. React는 변경되지 않고 인용에 렌더링을 통해 동일합니다.이것은 리셋 toggle
을 다시 만들 이유가 없다는 것을 의미한다.isToggledRef
의 값이 최신 값인지 확인하기 위해서, 우리는 useEffect
의존항 수조의 단일 isToggled
의존항과 함께 사용할 것이다.isToggled
가 변경된 경우에만 실행됩니다.
우리가 만든 갈고리를 사용할 때가 되었다.
const OptimizedBooleanState = () => {
const [isToggled, toggle] = useToggle(false);
const [randomNumber, setRandomNumber] = React.useState(Math.random());
const generateRandomNumber = React.useCallback(
() => setRandomNumber(Math.random()),
[],
);
return (
<div>
<div>
Current random number is <b>{randomNumber}</b>
<button style={{ marginLeft: '10px' }} onClick={generateRandomNumber}>
regenerate
</button>
</div>
<div>
Boolean is set to <b>{String(isToggled)}</b>.
</div>
<RendersCounter onClick={toggle} />
</div>
);
}
현재RenderCounter
는 영원히 다시 렌더링되지 않습니다!
Try it yourself
현대화하다
설명에 설명된 대로 이 경우에는 REF를 사용할 필요가 없습니다.이상적인 행위는 기능 상태 업데이트 프로그램을 통해 실현될 수 있다.현재 상태를 첫 번째 매개 변수로 하는 함수를 전달해야 합니다. setIsToggled
이것은 확실히 갈고리의 방식을 더욱 명확하게 한다.
setIsToggled(state => !state);
다음은 업데이트 버전useToggle
연결 모양입니다.
const useToggle = (initialState) => {
const [isToggled, setIsToggled] = React.useState(initialState);
// put [setIsToggled] into the useCallback's dependencies array
// this value never changes so the callback is not going to be ever re-created
const toggle = React.useCallback(
() => setIsToggled(state => !state),
[setIsToggled],
);
return [isToggled, toggle];
}
Try it yourself
결론
마지막으로 useCallback
는 최적화에 관한 것이다.리셋을 순수한 화살표 함수로 표시하면 코드가 정상적으로 작동할 수 있기 때문에 최적화와 코드 간결성 사이의 균형을 찾아야 합니다.
React-Hooks API 기능이 강력합니다.그것은 당신이 명확한 성명 코드를 작성할 수 있도록 합니다.만약 적절하게 처리된다면, 그것은 또한 응용 프로그램의 성능을 향상시킬 수 있다.
읽어주셔서 감사합니다!
Reference
이 문제에 관하여(React 갈고리를 사용하여 부울 상태 오른쪽 업데이트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/alexkhismatulin/update-boolean-state-right-with-react-hooks-3k2i
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
const toggle = () => setIsToggled(!isToggled);
import React from 'react';
const RendersCounter = ({ onClick }) => {
const rendersCountRef = React.useRef(0);
rendersCountRef.current += 1;
return (
<div>
<span>
RendersCounter rendered <b>{rendersCountRef.current}</b> time(s)
</span>
<button style={{ marginLeft: '10px' }} onClick={onClick}>
toggle
</button>
</div>
)
};
export default React.memo(RendersCounter);
const BasicBooleanState = () => {
const [isToggled, setIsToggled] = React.useState(false);
const toggle = React.useCallback(() => setIsToggled(!isToggled));
const [randomNumber, setRandomNumber] = React.useState(Math.random());
const generateRandomNumber = React.useCallback(
() => setRandomNumber(Math.random()),
[],
);
return (
<div>
<div>
Current random number is <b>{randomNumber}</b>
<button style={{ marginLeft: '10px' }} onClick={generateRandomNumber}>
regenerate
</button>
</div>
<div>
Boolean is set to <b>{String(isToggled)}</b>.
</div>
<RendersCounter onClick={toggle} />
</div>
);
}
React 문서 설명:
Every value referenced inside the function should also appear in the dependencies array
이 규칙을 따르지 않으면 콜백에 오래된 값이 나타날 수 있습니다.
toggle
콜백에는 isToggled
및 setIsToggled
두 개의 외부 값이 사용됩니다.그것들을 useCallback
의 의존 관계 그룹에 넣읍시다.const BasicBooleanState = () => {
const [isToggled, setIsToggled] = React.useState(false);
// here we added [isToggled, setIsToggled] as a second parameter
const toggle = React.useCallback(
() => setIsToggled(!isToggled),
[isToggled, setIsToggled],
);
const [randomNumber, setRandomNumber] = React.useState(Math.random());
const generateRandomNumber = React.useCallback(
() => setRandomNumber(Math.random()),
[],
);
return (
<div>
<div>
Current random number is <b>{randomNumber}</b>
<button style={{ marginLeft: '10px' }} onClick={generateRandomNumber}>
regenerate
</button>
</div>
<div>
Boolean is set to <b>{String(isToggled)}</b>.
</div>
<RendersCounter onClick={toggle} />
</div>
);
}
현재 RendersCounter
랜덤 수 변경 시 다시 렌더링되지 않습니다!우리는 리셋이 isToggled
또는 setIsToggled
변경될 때만 업데이트된다고 말했기 때문에 isToggled
변경이 없으면 인용에 있어서 같다.그러나
RendersCounter
에서 부울 상태를 전환하면 다시 렌더링됩니다.isToggled
에 변화가 생겼고 useCallback
의존항수조의 일부이기 때문에 의미가 있다.Try it yourself
리셋 최적화
리셋 toggle
문제를 해결하기 위해서는 직접적인 의존 isToggled
을 피하는 방법이 필요하지만, 리셋에는 실제 값이 있습니다.다음은 useRef
지원 서비스입니다.우리는 인용을 한 번만 만들고 isToggled
변경할 때 그 값을 업데이트할 수 있습니다.그리고 우리는 의존항수 그룹의 인용으로 isToggled
대체하고 그 자체를 리셋합니다. 이렇게!
사용자 정의 갈고리를 만듭니다. 현재 볼 상태와 전환 방법을 되돌려줍니다. 이 방법은 볼 값을 변경하고 있으며 영원히 다시 만들어지지 않습니다.
// it might be a project-level reusable hook
const useToggle = (initialState) => {
const [isToggled, setIsToggled] = React.useState(initialState);
const isToggledRef = React.useRef(isToggled);
// put [isToggledRef, setIsToggled] into the useCallback's dependencies array
// these values never change so the calllback is not going to be ever re-created
const toggle = React.useCallback(
() => setIsToggled(!isToggledRef.current),
[isToggledRef, setIsToggled],
);
// keep the value in isToggledRef actual
// when isToggled changes, isToggledRef is updated accordingly
React.useEffect(
() => {
isToggledRef.current = isToggled;
},
[isToggled],
);
return [isToggled, toggle];
}
우리는 isToggled
대신 isToggledRef
리셋을 만들기 위해 toggle
을 사용합니다.isToggledRef
및 setIsToggled
은 한 번만 생성됩니다. React는 변경되지 않고 인용에 렌더링을 통해 동일합니다.이것은 리셋 toggle
을 다시 만들 이유가 없다는 것을 의미한다.isToggledRef
의 값이 최신 값인지 확인하기 위해서, 우리는 useEffect
의존항 수조의 단일 isToggled
의존항과 함께 사용할 것이다.isToggled
가 변경된 경우에만 실행됩니다.
우리가 만든 갈고리를 사용할 때가 되었다.
const OptimizedBooleanState = () => {
const [isToggled, toggle] = useToggle(false);
const [randomNumber, setRandomNumber] = React.useState(Math.random());
const generateRandomNumber = React.useCallback(
() => setRandomNumber(Math.random()),
[],
);
return (
<div>
<div>
Current random number is <b>{randomNumber}</b>
<button style={{ marginLeft: '10px' }} onClick={generateRandomNumber}>
regenerate
</button>
</div>
<div>
Boolean is set to <b>{String(isToggled)}</b>.
</div>
<RendersCounter onClick={toggle} />
</div>
);
}
현재RenderCounter
는 영원히 다시 렌더링되지 않습니다!
Try it yourself
현대화하다
설명에 설명된 대로 이 경우에는 REF를 사용할 필요가 없습니다.이상적인 행위는 기능 상태 업데이트 프로그램을 통해 실현될 수 있다.현재 상태를 첫 번째 매개 변수로 하는 함수를 전달해야 합니다. setIsToggled
이것은 확실히 갈고리의 방식을 더욱 명확하게 한다.
setIsToggled(state => !state);
다음은 업데이트 버전useToggle
연결 모양입니다.
const useToggle = (initialState) => {
const [isToggled, setIsToggled] = React.useState(initialState);
// put [setIsToggled] into the useCallback's dependencies array
// this value never changes so the callback is not going to be ever re-created
const toggle = React.useCallback(
() => setIsToggled(state => !state),
[setIsToggled],
);
return [isToggled, toggle];
}
Try it yourself
결론
마지막으로 useCallback
는 최적화에 관한 것이다.리셋을 순수한 화살표 함수로 표시하면 코드가 정상적으로 작동할 수 있기 때문에 최적화와 코드 간결성 사이의 균형을 찾아야 합니다.
React-Hooks API 기능이 강력합니다.그것은 당신이 명확한 성명 코드를 작성할 수 있도록 합니다.만약 적절하게 처리된다면, 그것은 또한 응용 프로그램의 성능을 향상시킬 수 있다.
읽어주셔서 감사합니다!
Reference
이 문제에 관하여(React 갈고리를 사용하여 부울 상태 오른쪽 업데이트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/alexkhismatulin/update-boolean-state-right-with-react-hooks-3k2i
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
// it might be a project-level reusable hook
const useToggle = (initialState) => {
const [isToggled, setIsToggled] = React.useState(initialState);
const isToggledRef = React.useRef(isToggled);
// put [isToggledRef, setIsToggled] into the useCallback's dependencies array
// these values never change so the calllback is not going to be ever re-created
const toggle = React.useCallback(
() => setIsToggled(!isToggledRef.current),
[isToggledRef, setIsToggled],
);
// keep the value in isToggledRef actual
// when isToggled changes, isToggledRef is updated accordingly
React.useEffect(
() => {
isToggledRef.current = isToggled;
},
[isToggled],
);
return [isToggled, toggle];
}
const OptimizedBooleanState = () => {
const [isToggled, toggle] = useToggle(false);
const [randomNumber, setRandomNumber] = React.useState(Math.random());
const generateRandomNumber = React.useCallback(
() => setRandomNumber(Math.random()),
[],
);
return (
<div>
<div>
Current random number is <b>{randomNumber}</b>
<button style={{ marginLeft: '10px' }} onClick={generateRandomNumber}>
regenerate
</button>
</div>
<div>
Boolean is set to <b>{String(isToggled)}</b>.
</div>
<RendersCounter onClick={toggle} />
</div>
);
}
setIsToggled(state => !state);
const useToggle = (initialState) => {
const [isToggled, setIsToggled] = React.useState(initialState);
// put [setIsToggled] into the useCallback's dependencies array
// this value never changes so the callback is not going to be ever re-created
const toggle = React.useCallback(
() => setIsToggled(state => !state),
[setIsToggled],
);
return [isToggled, toggle];
}
마지막으로
useCallback
는 최적화에 관한 것이다.리셋을 순수한 화살표 함수로 표시하면 코드가 정상적으로 작동할 수 있기 때문에 최적화와 코드 간결성 사이의 균형을 찾아야 합니다.React-Hooks API 기능이 강력합니다.그것은 당신이 명확한 성명 코드를 작성할 수 있도록 합니다.만약 적절하게 처리된다면, 그것은 또한 응용 프로그램의 성능을 향상시킬 수 있다.
읽어주셔서 감사합니다!
Reference
이 문제에 관하여(React 갈고리를 사용하여 부울 상태 오른쪽 업데이트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/alexkhismatulin/update-boolean-state-right-with-react-hooks-3k2i텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)