Czy istnieją sposoby na symulowanie componentDidMount
komponentów funkcjonalnych w React za pomocą hooków?
javascript
reactjs
react-hooks
jeyko
źródło
źródło
useState
. Dla każdego, kto to czyta, pamiętaj, że pozostawienie drugiego argumentuundefined
spowoduje wywołanie efektu przy każdym renderowaniu (jeśli się nie mylę).Chociaż zaakceptowana odpowiedź działa, nie jest zalecana. Kiedy masz więcej niż jeden stan i używasz go z useEffect, ostrzeże Cię o dodaniu go do tablicy zależności lub w ogóle jej nieużywaniu.
Czasami powoduje to problem, który może dać nieprzewidywalne wyniki. Dlatego sugeruję, abyś trochę się postarał, aby przepisać swoją funkcję na klasę. Jest bardzo mało zmian i możesz mieć niektóre komponenty jako klasę, a niektóre jako funkcje. Nie jesteś zobowiązany do używania tylko jednej konwencji.
Weź to na przykład
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(...); }
i
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(...); }
To tylko przykład . więc nie mówmy o najlepszych praktykach lub potencjalnych problemach z kodem. Oba mają tę samą logikę, ale późniejsza działa tylko zgodnie z oczekiwaniami. Możesz uzyskać funkcjonalność komponentu componentDidMount, gdy useEffect będzie działał przez ten czas, ale wraz z rozwojem Twojej aplikacji mogą wystąpić pewne problemy. Więc zamiast przepisywać na tym etapie, lepiej zrobić to na wczesnym etapie.
Poza tym OOP nie jest takie złe, gdyby wystarczyło programowanie zorientowane na procedury, nigdy nie mielibyśmy programowania obiektowego. Czasami jest to bolesne, ale lepsze (technicznie. Pomijając kwestie osobiste).
źródło
Nie ma żadnych
componentDidMount
funkcjonalnych komponentów, ale React hooki zapewniają sposób na emulację zachowania za pomocąuseEffect
hooka.Przekaż pustą tablicę jako drugi argument,
useEffect()
aby uruchomić wywołanie zwrotne tylko po zamontowaniu.Przeczytaj dokumentację
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/[email protected]/umd/react.development.js"></script> <script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script> <div id="app"></div>
źródło
Nie ma dokładnego odpowiednika dla
componentDidMount
haków reakcyjnych.Z mojego doświadczenia wynika, że reakcja hooków wymaga innego sposobu myślenia podczas jej tworzenia i generalnie nie należy porównywać jej z metodami klasowymi, takimi jak
componentDidMount
.Z powiedział, że istnieją sposoby, które można wykorzystać do produkcji haków podobny efekt do
componentDidMount
.Rozwiązanie 1:
useEffect(() => { console.log("I have been mounted") }, [])
Rozwiązanie 2:
const num = 5 useEffect(() => { console.log("I will only run if my deps change: ", num) }, [num])
Rozwiązanie 3 (z funkcją):
useEffect(() => { const someFunc = () => { console.log("Function being run after/on mount") } someFunc() }, [])
Rozwiązanie 4 (useCallback):
const msg = "some message" const myFunc = useCallback(() => { console.log(msg) }, [msg]) useEffect(() => { myFunc() }, [myFunc])
Rozwiązanie 5 (kreatywność):
export default function useDidMountHook(callback) { const didMount = useRef(null) useEffect(() => { if (callback && !didMount.current) { didMount.current = true callback() } }) }
Warto zauważyć, że rozwiązanie 5 powinno być naprawdę używane tylko wtedy, gdy żadne z innych rozwiązań nie działa w twoim przypadku użycia . Jeśli zdecydujesz, że potrzebujesz rozwiązania 5, polecam użycie tego gotowego haka do montażu .
Źródło (bardziej szczegółowo): Używanie komponentu componentDidMount w zaczepach reagujących
źródło
dokładny odpowiednik hooka dla componentDidMount () to
useEffect(()=>{},[]);
mam nadzieję, że to pomocne :)
źródło
Chcesz użyć
useEffect()
, który, w zależności od tego, jak używasz funkcji, może działać podobnie jak componentDidMount ().Na przykład. można użyć niestandardowej
loaded
właściwości stanu, która jest początkowo ustawiona na false, i przełączyć ją na true podczas renderowania i uruchomić efekt tylko wtedy, gdy ta wartość się zmieni.Dokumentacja
źródło