React-함수 컴포넌트를 강제로 렌더링하는 방법은 무엇입니까?


84

함수 구성 요소가 있는데 강제로 다시 렌더링하고 싶습니다.

어떻게 할 수 있습니까?
인스턴스가 없기 때문에 this호출 할 수 없습니다 this.forceUpdate().


아니요, 상태 비 저장 구성 요소에는 상태가 없습니다. 대신 클래스를 사용하여
TryingToImprove

2
정말로 "기능적 구성 요소"가 아니라 " 상태 비 저장 구성 요소 "를 의미 합니까?
크리스

2
상태 비 저장 구성 요소를 업데이트하려면 전달 된 소품을 변경해야합니다.
fungusanthrax

소품 외에 후크 useState를 사용할 수 있으며 구성 요소가 변경되면 다시 렌더링됩니다
Hamid Shoja

답변:


134

🎉 이제 React 후크를 사용하여

반응 후크를 사용하여 이제 useState()함수 구성 요소를 호출 할 수 있습니다 .

useState()다음 두 가지의 배열을 반환합니다.
1. 현재 상태를 나타내는 값.
2. 그 세터. 이를 사용하여 값을 업데이트하십시오.

세터로 값을 업데이트하면 다시 렌더링 함수 구성 요소를 강제로 ,
처럼 forceUpdate수행합니다

import React, { useState } from 'react';

//create your forceUpdate hook
function useForceUpdate(){
    const [value, setValue] = useState(0); // integer state
    return () => setValue(value => ++value); // update the state to force render
}

function MyComponent() {
    // call your hook here
    const forceUpdate = useForceUpdate();

    return (
        <div>
            {/*Clicking on the button will force to re-render like force update does */}
            <button onClick={forceUpdate}>
                Click to re-render
            </button>
        </div>
    );
}

여기에서 데모를 찾을 수 있습니다 .

위의 구성 요소 useForceUpdate는 부울 상태 후크 ( useState)를 사용하는 사용자 지정 후크 함수 ( )를 사용합니다 . 부울 상태를 토글하므로 React에게 render 함수를 다시 실행하도록 지시합니다.

편집하다

이 답변의 이전 버전에서 스 니펫은 부울 값을 사용하고 forceUpdate(). 이제 답변을 편집 했으므로 코드 조각은 부울이 아닌 숫자를 사용합니다.

왜 ? (당신은 나에게 물어볼 것입니다)

한 번은 forceUpdate()두 개의 다른 이벤트에서 두 번 호출되어 원래 상태에서 부울 값을 재설정하고 구성 요소가 렌더링되지 않았기 때문입니다.

때문에에 useState(의 세터 setValue여기), React새와 이전 상태를 비교 하고 상태가 다른 경우에만 렌더링합니다.


3
해당 페이지에는 후크를 사용하여 호출하는 것에 대한 정보가 없습니다 forceUpdate.
jdelman

1
당분간은 더 낫습니다. 아직 힘든 후크도 아직 출시되지 않았기 때문에 베타 버전으로 사용할 수 있습니다. 그러나 일단 출시되면 클래스 구성 요소가 더 좋아질 이유가 없습니다. hooks를 사용하면 reactconf의 아래 비디오에서 볼 수 있듯이 클래스 구성 요소보다 코드가 더 깔끔해집니다. 어쨌든 문제는 이것이 가능한지입니다. 이제 대답은 후크 때문에 "아니오"에서 "예"로 변경됩니다. youtube.com/watch?v=wXLf18DsV-I
Yairopro 2018-12-22

1
안녕하세요 @DanteTheSmith. "최상위 수준"이란 말했듯이 조건이나 루프 내부에서 후크를 호출하지 않아야 함을 의미합니다. 하지만 다른 함수 내부에서 호출 할 수 있다고 말할 수 있습니다. 이는 사용자 지정 후크를 만드는 것을 의미합니다. Dan Abramov는 React conf에서 React hooks를 발표하면서 이것이 기능적 구성 요소간에 논리를 공유하는 가장 깨끗하고 가장 좋은 방법임을 분명히 보여줍니다. youtu.be/dpw9EHDh2bM?t=2753
Yairopro

1
"강제 렌더링을 위해"상태를 전환 할 필요가 없습니다. React가 이전 상태 값과 다음 상태 값을 "비교"하여 다시 렌더링해야하는지 여부를 결정하는 잘못된 인상을 만듭니다. 확실히 그렇지는 않지만.
meandre

1
@meandre 네, 확실히 비교합니다. 우리는 실제로 비교를하지 않는 useState클래스가 아니라 후크 에 대해 이야기하고 있습니다 setState(shouldUpdate 메소드를 구현하지 않는 한). 내가 게시 한 동일한 데모를 참조하십시오. 그러나에 사용 된 정적 값을 사용하면 setState다시 렌더링되지 않습니다. codesandbox.io/s/determined-rubin-8598l
Yairopro

47

React v16.8 업데이트 (2019 년 2 월 16 일 realease)

React 16.8이 후크와 함께 릴리스 된 이후로 함수 구성 요소는 이제 지속적으로 유지할 수 있습니다 state. 그 능력을 가진 당신은 지금 할 수있는 모방forceUpdate:

이 접근 방식은 다시 고려해야하며 대부분의 경우 업데이트를 강제해야 할 때 잘못된 작업을 수행 할 수 있습니다.


반응 전 16.8.0

당신은 할 수 없음, 국가없는 기능 구성 요소는 정상 functions반환 것을 jsx당신이에서 연장되지 않습니다으로는 수명주기 방법 반응에, 당신이 어떤 액세스 할 수 없습니다 React.Component.

함수 컴포넌트를 render클래스 컴포넌트 의 메소드 부분 으로 생각하십시오 .


ofc 할 수 있습니다. 여기에 오는 소품을 변경
마리아 지크 Šedaj에게

5
그건 아니에요 강제 A가 렌더링 다만 정상이, 다시 렌더링합니다. 렌더링 을 강제 하려는 경우 일반적으로 실행하도록 설계되지 않은 경우 (예 : 새롭 props거나 state변경된 사항 이없는 경우) render 메서드를 실행하려는 경우 입니다. 상태 비 저장 구성 요소 에는 기능 이 없기 때문에 렌더링 기능을 강제 할 수 없습니다render . 상태 비 저장 구성 요소는 extends React.Component을 반환하는 일반 함수 가 아닙니다 jsx.
Sagiv bg

"업데이트를 강제해야 할 때 아마도 뭔가 잘못하고있을 것입니다."에 대한 소품-그게 사실이라는 것을 알고 있었지만 이로 인해 useEffect 후크를 한 번 더 자세히 살펴보아야했습니다.
Methodician 19

12

공식 FAQ ( https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate )는 이제 정말로 필요한 경우 다음 방법을 권장 합니다.

  const [ignored, forceUpdate] = useReducer(x => x + 1, 0);

  function handleClick() {
    forceUpdate();
  }

나는 그것을 결코 몰랐습니다
Charith Jayasanka

9
코드를 7 바이트 더 짧게 만들고 사용하지 않는 변수를 만들지 않을 수 있습니다.const [, forceUpdate] = useReducer(x => x + 1, 0);
Konstantin Smolyanin

7

use-force-update 라는 타사 라이브러리를 사용 하여 반응 기능 구성 요소를 강제로 렌더링했습니다. 매력처럼 작동했습니다. 프로젝트에서 패키지 가져 오기를 사용하고 이와 같이 사용하십시오.

import useForceUpdate from 'use-force-update';

const MyButton = () => {

  const forceUpdate = useForceUpdate();

  const handleClick = () => {
    alert('I will re-render now.');
    forceUpdate();
  };

  return <button onClick={handleClick} />;
};

2
클릭을 저장하려면 다른 답변에서 언급했듯이 useForceUpdate사용 하십시오 useCallback. 이 lib는 몇 가지 키 입력을 저장하는 유틸리티 lib입니다.
asyncwait

오 감사합니다. 나는 그것을 몰랐다. :)
Charith Jayasanka

6

면책 조항 : 문제에 대한 답이 아닙니다.

여기에 중요한 메모를 남겨주세요 :

상태 비 저장 구성 요소를 강제 업데이트하려는 경우 디자인에 문제가있을 가능성이 있습니다.

다음 경우를 고려하십시오.

  1. 상태를 변경하고 부모 구성 요소를 다시 렌더링 할 수있는 자식 구성 요소에 setter (setState)를 전달합니다.
  2. 상태 해제 고려
  3. 연결된 구성 요소에서 자동으로 다시 렌더링을 강제 할 수있는 Redux 저장소에 해당 상태를 넣는 것을 고려하십시오.

1
구성 요소 업데이트를 비활성화하고 원할 때 강제로 적용해야하는 경우가 있습니다 (움직이는 눈금자, 모든 움직임의 값을 업데이트하고 업데이트로 인해 깜박임 동작이 발생 함). 그래서 저는이 컴포넌트에 클래스를 사용하기로 결정했고 렌더링 동작에 대한 심층적 인 제어가 필요한 모든 컴포넌트는 클래스에서 수행되어야합니다. 현재 후크는이 동작에 대한 미세한 제어를 제공하지 않기 때문입니다. (현재 React 버전은 16.12입니다.)
Michael Wallace

저도 같은 생각을했지만 빠른 수정을 원했기 때문에 강제 업데이트를 사용했습니다.
Charith Jayasanka

현실 세계에서는 그 용도가 있습니다. 완벽한 것은 없으며, 소프트웨어를 출시하고 싶다면 다른 사람이 문제를 해결하는 방법을 더 잘 알고 있어야합니다.
Brain2000

1

컴포넌트에 prop을 추가하고 stateless 컴포넌트의 부모 컴포넌트에 state를 추가한다면 후크를 명시 적으로 사용하지 않고도이 작업을 수행 할 수 있습니다.

const ParentComponent = props => {
  const [updateNow, setUpdateNow] = useState(true)

  const updateFunc = () => {
    setUpdateNow(!updateNow)
  }

  const MyComponent = props => {
    return (<div> .... </div>)
  }

  const MyButtonComponent = props => {
    return (<div> <input type="button" onClick={props.updateFunc} />.... </div>)
  }

  return (
    <div> 
      <MyComponent updateMe={updateNow} />
      <MyButtonComponent updateFunc={updateFunc}/>
    </div>
  )
}

1

받아 들여지는 대답은 좋습니다. 이해하기 쉽게하기 위해서입니다.

구성 요소 예 :

export default function MyComponent(props) {

    const [updateView, setUpdateView] = useState(0);

    return (
        <>
            <span style={{ display: "none" }}>{updateView}</span>
        </>
    );
}

다시 렌더링을 강제하려면 아래 코드를 호출하십시오.

setUpdateView((updateView) => ++updateView);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.