아래 후크 예제 고려
import { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
기본적으로 this.forceUpdate () 메서드를 사용하여 아래 예제와 같이 React 클래스 구성 요소에서 구성 요소를 즉시 다시 렌더링하도록합니다.
class Test extends Component{
constructor(props){
super(props);
this.state = {
count:0,
count2: 100
}
this.setCount = this.setCount.bind(this);//how can I do this with hooks in functional component
}
setCount(){
let count = this.state.count;
count = count+1;
let count2 = this.state.count2;
count2 = count2+1;
this.setState({count});
this.forceUpdate();
//before below setState the component will re-render immediately when this.forceUpdate() is called
this.setState({count2: count
}
render(){
return (<div>
<span>Count: {this.state.count}></span>.
<button onClick={this.setCount}></button>
</div>
}
}
하지만 내 쿼리는 위의 기능 구성 요소를 후크로 즉시 다시 렌더링하도록 강제 할 수 있습니까?
답변
내부적으로 사용하기 때문에 useState
또는 으로 가능합니다 .useReducer
useState
useReducer
const [, updateState] = React.useState();
const forceUpdate = React.useCallback(() => updateState({}), []);
forceUpdate
정상적인 상황에서 사용하기위한 것이 아니라 테스트 또는 기타 뛰어난 경우에만 사용할 수 있습니다. 이 상황은보다 일반적인 방법으로 해결할 수 있습니다.
setCount
부적절한 사용의 예입니다 forceUpdate
, setState
성능상의 이유로 비동기 및 상태 업데이트가 제대로 수행되지 않았다해서 동기로 강제되어서는 안된다. 상태가 이전에 설정된 상태에 의존하는 경우 업데이트 기능 으로 수행해야합니다 .
이전 상태를 기반으로 상태를 설정해야하는 경우 아래 업데이트 프로그램 인수에 대해 읽어보세요.
<…>
업데이터 함수에서 수신 한 상태와 소품은 모두 최신 상태를 보장합니다. 업데이트 프로그램의 출력은 상태와 얕게 병합됩니다.
setCount
목적이 불명확하기 때문에 예시가 아닐 수 있지만 이것은 업데이트 프로그램 기능의 경우입니다.
setCount(){
this.setState(({count}) => ({ count: count + 1 }));
this.setState(({count2}) => ({ count2: count + 1 }));
this.setState(({count}) => ({ count2: count + 1 }));
}
이것은 콜백으로 사용되는 함수를 더 잘 기억해야한다는 점을 제외하고는 후크로 1 : 1로 변환됩니다.
const [state, setState] = useState({ count: 0, count2: 100 });
const setCount = useCallback(() => {
setState(({count}) => ({ count: count + 1 }));
setState(({count2}) => ({ count2: count + 1 }));
setState(({count}) => ({ count2: count + 1 }));
}, []);
답변
다른 사람들이 언급했듯이 useState
작동합니다. mobx-react-lite 가 업데이트를 구현 하는 방법 은 다음과 같습니다. 유사한 작업을 수행 할 수 있습니다.
새 후크 정의, useForceUpdate
–
import { useState, useCallback } from 'react'
export function useForceUpdate() {
const [, setTick] = useState(0);
const update = useCallback(() => {
setTick(tick => tick + 1);
}, [])
return update;
}
구성 요소에서 사용-
const forceUpdate = useForceUpdate();
if (...) {
forceUpdate(); // force re-render
}
참조 https://github.com/mobxjs/mobx-react-lite/blob/master/src/utils.ts 및 https://github.com/mobxjs/mobx-react-lite/blob/master/src/useObserver .ts
답변
일반적으로 업데이트를 트리거하려는 모든 상태 처리 방법을 사용할 수 있습니다.
TypeScript 사용
useState
const forceUpdate: () => void = React.useState()[1].bind(null, {}) // see NOTE below
useReducer
const forceUpdate = React.useReducer(() => ({}), {})[1] as () => void
커스텀 후크로
이처럼 선호하는 접근 방식을 포장하십시오.
function useForceUpdate(): () => void {
return React.useReducer(() => ({}), {})[1] as () => void // <- paste here
}
어떻게 작동합니까?
” 업데이트를 트리거하려면 “ 은 어떤 값이 변경되었으며 컴포넌트를 다시 렌더링해야한다고 React 엔진에 알리는 것을 의미합니다.
[, setState]
from useState()
에는 매개 변수 가 필요합니다. 새로운 객체를 바인딩하여 제거합니다 {}
.
() => ({})
in useReducer
은 액션이 전달 될 때마다 새로운 객체를 반환하는 더미 감속기입니다.
{}
(새 객체) 는 상태에서 참조를 변경하여 업데이트를 트리거하기 위해 필요합니다.
추신 : 내부적으로 useState
포장 useReducer
합니다. 출처
참고 : useState와 함께 .bind를 사용하면 렌더링간에 함수 참조가 변경됩니다. 여기 에서이미 설명했듯이 useCallback 안에 넣을수는 있지만 섹시한 one-liner ™ 는 아닙니다. Reducer 버전은 이미 렌더링간에 참조 동등성을 유지 합니다. props에서 forceUpdate 함수를 전달하려는 경우 중요합니다.
일반 JS
const forceUpdate = React.useState()[1].bind(null, {}) // see NOTE above
const forceUpdate = React.useReducer(() => ({}))[1]
답변
@MinhKha의 답변에 대한 대안 :
다음으로 훨씬 더 깨끗해질 수 있습니다 useReducer
.
const [, forceUpdate] = useReducer(x => x + 1, 0);
사용법 :
forceUpdate()
-매개 변수없는 클리너
답변
다음과 같이 useState를 간단히 정의 할 수 있습니다.
const [, forceUpdate] = React.useState(0);
그리고 사용법 : forceUpdate(n => !n)
이 도움을 바랍니다!
답변
React Hooks FAQ 공식 솔루션 forceUpdate
:
const [_, forceUpdate] = useReducer((x) => x + 1, 0);
// usage
<button onClick={forceUpdate}>Force update</button>
작업 예
답변
구성 요소가 상태 및 소품에만 의존하도록하는 것이 바람직하며 예상대로 작동하지만 구성 요소를 강제로 다시 렌더링하는 함수가 필요한 경우 다음을 사용할 수 있습니다. useState
하는 함수가 필요한 경우 후크를 필요할 때 함수를 호출 .
예
const { useState, useEffect } = React;
function Foo() {
const [, forceUpdate] = useState();
useEffect(() => {
setTimeout(forceUpdate, 2000);
}, []);
return <div>{Date.now()}</div>;
}
ReactDOM.render(<Foo />, document.getElementById("root"));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>