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.