Чи існують способи моделювання componentDidMountфункціональних компонентів React за допомогою гачків?
Відповіді:
Для стабільної версії хуків (React версії 16.8.0+)
Для componentDidMount
useEffect(() => {
// Your code here
}, []);
Для componentDidUpdate
useEffect(() => {
// Your code here
}, [yourDependency]);
Для componentWillUnmount
useEffect(() => {
// componentWillUnmount
return () => {
// Your code here
}
}, [yourDependency]);
Отже, у цій ситуації вам потрібно передати свою залежність у цей масив. Припустимо, у вас такий стан
const [count, setCount] = useState(0);
І щоразу, коли кількість збільшується, ви хочете повторно відтворити свій функціональний компонент. Тоді ваш useEffectповинен виглядати так
useEffect(() => {
// <div>{count}</div>
}, [count]);
Таким чином, щоразу, коли ваш підрахунок оновлень, ваш компонент буде рендерінг. Сподіваємось, це трохи допоможе.
useState. Будь-хто, хто читає це, майте на увазі, що залишення другого аргументу undefinedпризведе до того, що ваш ефект спрацює на кожному рендері (якщо я не помиляюся).
Хоча прийнята відповідь працює, вона не рекомендується. Коли у вас є більше одного стану, і ви використовуєте його з useEffect, він видасть вам попередження про додавання його до масиву залежностей або взагалі його використання.
Це іноді спричиняє проблему, яка може дати вам непередбачуваний результат. Тому я пропоную вам докласти трохи зусиль, щоб переписати свою функцію як клас. Змінів дуже мало, і ви можете мати деякі компоненти як клас, а деякі як функції. Ви не зобов’язані користуватися лише однією умовою.
Візьмемо це для прикладу
function App() {
const [appointments, setAppointments] = useState([]);
const [aptId, setAptId] = useState(1);
useEffect(() => {
fetch('./data.json')
.then(response => response.json())
.then(result => {
const apts = result.map(item => {
item.aptId = aptId;
console.log(aptId);
setAptId(aptId + 1);
return item;
})
setAppointments(apts);
});
}, []);
return(...);
}
і
class App extends Component {
constructor() {
super();
this.state = {
appointments: [],
aptId: 1,
}
}
componentDidMount() {
fetch('./data.json')
.then(response => response.json())
.then(result => {
const apts = result.map(item => {
item.aptId = this.state.aptId;
this.setState({aptId: this.state.aptId + 1});
console.log(this.state.aptId);
return item;
});
this.setState({appointments: apts});
});
}
render(...);
}
Це лише для прикладу . тому не можна говорити про найкращі практики чи потенційні проблеми з кодом. І те, і інше має однакову логіку, але пізніше працює лише за очікуванням. Ви можете отримати функціонал componentDidMount із запущеним useEffect на цей час, але в міру зростання вашого додатка є ймовірність того, що ви МОЖЕТЕ зіткнутися з деякими проблемами. Отже, замість того, щоб переписувати на цьому етапі, краще робити це на ранній стадії.
До того ж ООП не настільки поганий, якби було достатньо процедурно-орієнтованого програмування, ми ніколи не мали б об’єктно-орієнтованого програмування. Іноді це боляче, але краще (технічно. Особисті питання в сторону).
Там немає componentDidMountна функціональних компонентах, але Реагувати Гачки забезпечують спосіб , яким Ви можете емулювати поведінка за допомогою useEffectгачка.
Передайте порожній масив як другий аргумент, useEffect()щоб запустити лише зворотний виклик лише під час монтування.
Будь ласка, прочитайте документацію наuseEffect .
function ComponentDidMount() {
const [count, setCount] = React.useState(0);
React.useEffect(() => {
console.log('componentDidMount');
}, []);
return (
<div>
<p>componentDidMount: {count} times</p>
<button
onClick={() => {
setCount(count + 1);
}}
>
Click Me
</button>
</div>
);
}
ReactDOM.render(
<div>
<ComponentDidMount />
</div>,
document.querySelector("#app")
);
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
Ви хочете використовувати useEffect(), яке, залежно від того, як ви використовуєте функцію, може діяти так само, як componentDidMount ().
Напр. Ви можете скористатися спеціальною loadedвластивістю стану, для якої спочатку встановлено значення false, і перемкнути її на true при отрисуванні, і запускати ефект лише тоді, коли це значення змінюється.