У мене є функціональний компонент, і я хочу змусити його повторно відтворити.
Як я можу це зробити?
Оскільки екземпляра немає this
, я не можу зателефонувати this.forceUpdate()
.
У мене є функціональний компонент, і я хочу змусити його повторно відтворити.
Як я можу це зробити?
Оскільки екземпляра немає this
, я не можу зателефонувати this.forceUpdate()
.
Відповіді:
Використовуючи реакційні гачки, тепер ви можете викликати useState()
свій функціональний компонент.
useState()
поверне масив із 2 речей:
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 повторно запустити функцію візуалізації.
У старій версії цієї відповіді фрагмент використовував логічне значення та вмикав його forceUpdate()
. Тепер, коли я відредагував свою відповідь, фрагмент використовує число, а не логічне значення.
Чому? (ви б запитали мене)
Оскільки одного разу зі мною трапилося, що мою forceUpdate()
викликали двічі згодом із 2 різних подій, і, таким чином, вона скидала булеве значення у вихідному стані, і компонент ніколи не відображався.
Тому що в програмі useState
встановлення ( setValue
тут) React
порівняйте попередній стан з новим і обробляйте, лише якщо стан інший.
forceUpdate
.
useState
хук, а не про клас ', setState
який справді не робить порівняння (якщо ви не реалізуєте метод shouldUpdate). Подивіться ту саму демонстраційну демонстрацію, яку я опублікував, але зі статичним значенням, що використовується для setState
, вона не відображається знову: codesandbox.io/s/determined-rubin-8598l
Реакція оновлення v16.8 (випуск 16 лютого 2019 р.)
Оскільки реакція 16.8, випущена за допомогою гачків , функціональні компоненти тепер мають здатність утримувати стійкість state
. З цією здатністю ви можете тепер імітують A forceUpdate
:
Зверніть увагу, що цей підхід слід переглянути і в більшості випадків, коли вам потрібно примусити оновити, ви, мабуть, робите щось не так.
До реагування 16.8.0
Ні, ви не можете, функціональні компоненти без станів - це звичайна норма, functions
яка повертається jsx
, у вас немає доступу до методів життєвого циклу React, оскільки ви не поширюєтеся на React.Component
.
Подумайте про функцію-компонент як про render
частину методу компонентів класу.
props
або state
змін. ви не можете примусити функцію візуалізації, оскільки функція не існує render
на компонентах без стану. Безкомпонентні компоненти - це не extends
React.Component
просто функції, які повертаються jsx
.
Офіційне поширене запитання ( https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate ) зараз рекомендує такий спосіб, якщо вам дійсно потрібно це зробити:
const [ignored, forceUpdate] = useReducer(x => x + 1, 0);
function handleClick() {
forceUpdate();
}
const [, forceUpdate] = useReducer(x => x + 1, 0);
Я використовував сторонню бібліотеку під назвою 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} />;
};
useForceUpdate
використовує, useCallback
як згадано в інших відповідях. Ця бібліотека - лише службова бібліотека, щоб заощадити кілька натискань клавіш.
Застереження: НЕ ВІДПОВІДЬ НА ПРОБЛЕМУ.
Залишаючи тут важливу примітку:
Якщо ви намагаєтесь оновити компонент без громадянства, швидше за все, щось не так з вашим дизайном.
Розглянемо такі випадки:
Це можна зробити без явного використання хуків за умови, що ви додаєте prop до свого компонента та стан до батьківського компонента компонента без стану:
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>
)
}
Прийнята відповідь хороша. Тільки для того, щоб було легше зрозуміти.
Приклад компонента:
export default function MyComponent(props) {
const [updateView, setUpdateView] = useState(0);
return (
<>
<span style={{ display: "none" }}>{updateView}</span>
</>
);
}
Щоб примусити повторний візуалізацію, зателефонуйте нижче:
setUpdateView((updateView) => ++updateView);