답변:
당신은 기존의 라이프 사이클 방법 (어떤 사용할 수 없습니다 componentDidMount
, componentDidUpdate
, componentWillUnmount
후크에 등). 클래스 구성 요소에서만 사용할 수 있습니다. 그리고 후크를 사용하면 기능적 구성 요소에서만 사용할 수 있습니다. 아래 줄은 React 문서에서 나온 것입니다.
당신이 클래스 수명주기 방법 반응에 익숙하다면, 당신은 생각할 수
useEffect
로 후크componentDidMount
,componentDidUpdate
및componentWillUnmount
결합.
기능 구성 요소의 클래스 구성 요소에서 이러한 수명주기 방법을 모방 할 수 있습니다.
componentDidMount
구성 요소가 마운트 될 때 내부 코드 가 한 번 실행됩니다. useEffect
이 동작에 해당하는 후크는
useEffect(() => {
// Your code here
}, []);
두 번째 매개 변수 (빈 배열)를 확인하십시오. 한 번만 실행됩니다.
두 번째 매개 변수 가 없으면useEffect
구성 요소의 모든 렌더링 에서 후크가 호출되어 위험 할 수 있습니다.
useEffect(() => {
// Your code here
});
componentWillUnmount
이벤트 리스너 제거, 타이머 취소 등과 같은 정리에 사용됩니다. 아래와 같이 이벤트 리스너를 추가 componentDidMount
하고 제거 한다고 가정하십시오 componentWillUnmount
.
componentDidMount() {
window.addEventListener('mousemove', () => {})
}
componentWillUnmount() {
window.removeEventListener('mousemove', () => {})
}
위 코드와 동등한 후크는 다음과 같습니다.
useEffect(() => {
window.addEventListener('mousemove', () => {});
// returned function will be called on component unmount
return () => {
window.removeEventListener('mousemove', () => {})
}
}, [])
useEffect()
기능을 정말로 이해한다 . 고마워.
componentWillMount
componentWillMount
아니라 componentWillUnmount
. 이 답변은 실제로 질문에 전혀 대답하지 않으며 OP가 이미 암시 한 내용을 반복합니다.
대부분의 경우에 useComponentDidMount
사용할 도구입니다. 컴포넌트가 마운트 된 후 (초기 렌더링) 한 번만 실행됩니다.
const useComponentDidMount = func => useEffect(func, []);
클래스 구성 요소 componentWillMount
는 레거시로 간주됩니다. 구성 요소가 마운트되기 전에 코드를 한 번만 실행해야하는 경우 생성자를 사용할 수 있습니다. 여기에 대한 자세한 내용 . 기능적 구성 요소에는 생성자와 같은 기능이 없으므로 구성 요소를 마운트하기 전에 후크를 사용하여 코드를 한 번만 실행하면 특정 경우에 적합합니다. 사용자 정의 후크로 달성 할 수 있습니다.
const useComponentWillMount = func => {
const willMount = useRef(true);
if (willMount.current) {
func();
}
willMount.current = false;
};
그러나 함정이 있습니다. 비동기 적으로 상태를 설정하는 데 사용하지 마십시오 (예 : 서버 요청 후. 초기 렌더링에 영향을 미치지 않을 것으로 예상 할 수 있음). 이러한 경우는useComponentDidMount
.
const Component = (props) => {
useComponentWillMount(() => console.log("Runs only once before component mounts"));
useComponentDidMount(() => console.log("Runs only once after component mounts"));
...
return (
<div>{...}</div>
);
}
componentWillMount
기반한 기능 구현 useEffect
에는 두 가지 문제가 있습니다. 첫 번째는 기능적 구성 요소에 장착 수명주기가 없으며 구성 요소가 렌더링 된 후 두 후크가 모두 실행되므로 Runs only once before component mounts
오해의 소지가 있다는 것입니다. 두 번째는 componentWillMount
서버 렌더링에서 호출되지만 useEffect
그렇지 않습니다. 많은 라이브러리는 UNSAFE_componentWillMount
현재 부작용이 서버 측을 트리거하는 유일한 방법이기 때문에 여전히 의존합니다 .
reactjs.org에 따르면 componentWillMount는 향후 지원되지 않을 것입니다. https://reactjs.org/docs/react-component.html#unsafe_componentwillmount
componentWillMount를 사용할 필요가 없습니다.
구성 요소가 마운트되기 전에 무언가를 수행하려면 constructor ()에서 수행하십시오.
네트워크 요청을하려면 componentWillMount에서 수행하지 마십시오. 이렇게하면 예기치 않은 버그가 발생하기 때문입니다.
componentDidMount에서 네트워크 요청을 수행 할 수 있습니다.
도움이 되길 바랍니다.
08/03/2019에 업데이트 됨
componentWillMount를 요청하는 이유는 렌더링 전에 상태를 초기화하려고하기 때문일 수 있습니다.
useState에서 수행하십시오.
const helloWorld=()=>{
const [value,setValue]=useState(0) //initialize your state here
return <p>{value}</p>
}
export default helloWorld;
또는 아마도 원래 코드가 다음과 같은 경우 componentWillMount에서 함수를 실행하려고 할 수 있습니다.
componentWillMount(){
console.log('componentWillMount')
}
후크를 사용하면 라이프 사이클 방법을 제거하기 만하면됩니다.
const hookComponent=()=>{
console.log('componentWillMount')
return <p>you have transfered componeWillMount from class component into hook </p>
}
useEffect에 대한 첫 번째 답변에 무언가를 추가하고 싶습니다.
useEffect(()=>{})
useEffect는 모든 렌더에서 실행되며 componentDidUpdate, componentDidMount 및 ComponentWillUnmount의 조합입니다.
useEffect(()=>{},[])
useEffect에 빈 배열을 추가하면 구성 요소가 마운트 될 때만 실행됩니다. useEffect가 전달한 배열을 비교하기 때문입니다. 따라서 빈 배열 일 필요는 없으며 변경되지 않는 배열 일 수도 있습니다. 예를 들어 [1,2,3] 또는 [ '1,2'] 일 수 있습니다. useEffect는 여전히 구성 요소가 마운트 된 경우에만 실행됩니다.
한 번만 실행하거나 매 렌더링 후에 실행하는지 여부에 따라 다릅니다. 수행중인 작업을 알고있는 한 배열을 추가하는 것을 잊어 버린 경우 위험하지 않습니다.
후크 샘플을 만들었습니다. 그것을 확인하시기 바랍니다.
https://codesandbox.io/s/kw6xj153wr
21/08/2019에 업데이트 됨
위의 답변을 쓴 이후로 백인이었습니다. 주의를 기울여야 할 것이 있습니다. 사용할 때
useEffect(()=>{},[])
react는 배열 []에 전달한 값을 비교할 때 Object.is ()를 사용하여 비교합니다. 객체를 전달하면
useEffect(()=>{},[{name:'Tom'}])
이것은 정확히 다음과 같습니다 :
useEffect(()=>{})
Object.is ()가 객체를 비교할 때 값 자체가 아닌 참조를 비교하기 때문에 매번 다시 렌더링됩니다. 참조가 다르기 때문에 {} === {}가 false를 반환하는 이유와 동일합니다. 여전히 참조 자체가 아닌 객체 자체를 비교하려면 다음과 같이 할 수 있습니다.
useEffect(()=>{},[JSON.stringify({name:'Tom'})])
useLayoutEffect
[]
기능이 실제로 다음과 비슷한 경우 빈 옵저버 세트 ( ) 로이를 수행 할 수componentWillMount
. 첫 번째 내용이 DOM에 도달하기 전에 실행됩니다. 실제로 두 가지 업데이트가 있지만 화면에 그리기 전에 동기화됩니다.
예를 들면 다음과 같습니다.
function MyComponent({ ...andItsProps }) {
useLayoutEffect(()=> {
console.log('I am about to render!');
},[]);
return (<div>some content</div>);
}
useState
이니셜 라이저 / 세터와 의 이점 useEffect
은 렌더 패스를 계산할 수는 있지만 사용자가 알 수있는 DOM에 대한 실제 재 렌더링은 없으며 첫 번째 주목할만한 렌더링 전에 실행 됩니다.useEffect
. 단점은 물론 화면에 페인팅하기 전에 확인 / 업데이트가 수행되어야하기 때문에 첫 번째 렌더링에서 약간의 지연이 있습니다. 그러나 실제로는 사용 사례에 따라 다릅니다.
개인적으로 생각 useMemo
하면 무거운 것을해야하는 틈새 시장에서는 괜찮습니다. 명심할 한 예외는 표준입니다.
이것은 useRef
후크를 사용하여 기능 구성 요소에서 생성자를 시뮬레이션하는 방법입니다 .
function Component(props) {
const willMount = useRef(true);
if (willMount.current) {
console.log('This runs only once before rendering the component.');
willMount.current = false;
}
return (<h1>Meow world!</h1>);
}
수명주기 예제는 다음과 같습니다.
function RenderLog(props) {
console.log('Render log: ' + props.children);
return (<>{props.children}</>);
}
function Component(props) {
console.log('Body');
const [count, setCount] = useState(0);
const willMount = useRef(true);
if (willMount.current) {
console.log('First time load (it runs only once)');
setCount(2);
willMount.current = false;
} else {
console.log('Repeated load');
}
useEffect(() => {
console.log('Component did mount (it runs only once)');
return () => console.log('Component will unmount');
}, []);
useEffect(() => {
console.log('Component did update');
});
useEffect(() => {
console.log('Component will receive props');
}, [count]);
return (
<>
<h1>{count}</h1>
<RenderLog>{count}</RenderLog>
</>
);
}
[Log] Body
[Log] First time load (it runs only once)
[Log] Body
[Log] Repeated load
[Log] Render log: 2
[Log] Component did mount (it runs only once)
[Log] Component did update
[Log] Component will receive props
물론 클래스 구성 요소에는 Body
단계 가 없으므로 기능과 클래스의 개념이 다르기 때문에 1 : 1 시뮬레이션을 수행 할 수 없습니다.
첫 렌더링 전에 함수를 한 번 실행하는 사용자 지정 후크를 작성했습니다.
useBeforeFirstRender.js
import { useState, useEffect } from 'react'
export default (fun) => {
const [hasRendered, setHasRendered] = useState(false)
useEffect(() => setHasRendered(true), [hasRendered])
if (!hasRendered) {
fun()
}
}
용법:
import React, { useEffect } from 'react'
import useBeforeFirstRender from '../hooks/useBeforeFirstRender'
export default () => {
useBeforeFirstRender(() => {
console.log('Do stuff here')
})
return (
<div>
My component
</div>
)
}
componentDidMount
와 componentWillUnmount
함께 구현하는 좋은 해결 방법이 있습니다 useEffect
.
설명서에 따라 useEffect
"정리"기능을 반환 할 수 있습니다. 이 함수는 첫 번째 useEffect
호출에서 호출되지 않고 후속 호출에서만 호출됩니다.
따라서 useEffect
의존성이없는 후크를 사용하면 구성 요소를 마운트 할 때만 후크가 호출되고 구성 요소를 마운트 해제 할 때 "정리"기능이 호출됩니다.
useEffect(() => {
console.log('componentDidMount');
return () => {
console.log('componentWillUnmount');
};
}, []);
정리 리턴 함수 호출은 구성 요소가 마운트 해제 된 경우에만 호출됩니다.
도움이 되었기를 바랍니다.
useEffect
호출하면 동일한 기능을 얻을 componentWillMount
하고 componentWillUnmount
멋지고 깨끗한 방법
useEffect
렌더링 후에 만 실행 componentWillMount
되고 구성 요소가 렌더링되기 전에 실행됩니다.
componentDidMount
않았다 componentWillMount
. 나는 그 질문에서 그것을 놓쳤다.
useMemo 후크를 해킹하여 componentWillMount 수명주기 이벤트를 모방 할 수 있습니다. 그냥 해:
const Component = () => {
useMemo(() => {
// componentWillMount events
},[]);
useEffect(() => {
// componentWillMount events
return () => {
// componentWillUnmount events
}
}, []);
};
상태와 상호 작용하기 전에 useMemo 후크를 유지해야합니다. 이것은 의도 된 방식이 아니지만 모든 componentWillMount 문제에 효과적이었습니다.
이것은 useMemo가 실제로 값을 리턴 할 필요가없고 실제로이를 다른 값으로 사용할 필요가 없기 때문에 작동하지만 한 번만 실행되는 종속성 ( "[]")과 컴포넌트의 맨 위에있는 종속성을 기반으로하는 값을 기억하기 때문입니다. 구성 요소가 다른 것보다 먼저 마운트 될 때 한 번 실행됩니다.
https://reactjs.org/docs/hooks-reference.html#usememo
useMemo에 전달 된 함수는 렌더링 중에 실행됩니다. 렌더링하는 동안 일반적으로하지 않는 작업은 수행하지 마십시오. 예를 들어 부작용은 useMemo가 아니라 useEffect에 속합니다.
벤 잉어의 대답은 나에게 유효한 것 같습니다.
그러나 우리가 기능적인 방법을 사용하고 있기 때문에 또 다른 접근 방식은 폐쇄 및 HoC의 이점을 얻을 수 있습니다
const InjectWillmount = function(Node, willMountCallback) {
let isCalled = true;
return function() {
if (isCalled) {
willMountCallback();
isCalled = false;
}
return Node;
};
};
그런 다음 사용하십시오 :
const YourNewComponent = InjectWillmount(<YourComponent />, () => {
console.log("your pre-mount logic here");
});
원래 질문에 대한 짧은 대답 , componentWillMount
React Hooks와 함께 사용 하는 방법 :
componentWillMount
되어 사용되지 않으며 기존의 생각 . 반응 추천 :
일반적으로 state를 초기화하기 위해 constructor ()를 사용하는 것이 좋습니다.
이제 후크 FAQ 에서 함수 구성 요소에 대한 클래스 생성자에 해당하는 내용을 확인하십시오.
생성자 : 함수 구성 요소에는 생성자가 필요하지 않습니다. useState 호출에서 상태를 초기화 할 수 있습니다. 초기 상태를 계산하는 것이 비싸면 useState에 함수를 전달할 수 있습니다.
따라서 사용 예는 componentWillMount
다음과 같습니다.
const MyComp = () => {
const [state, setState] = useState(42) // set initial value directly in useState
const [state2, setState2] = useState(createInitVal) // call complex computation
return <div>{state},{state2}</div>
};
const createInitVal = () => { /* ... complex computation or other logic */ return 42; };