Чи існують способи моделювання 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 при отрисуванні, і запускати ефект лише тоді, коли це значення змінюється.