Existem maneiras de simular componentDidMount
componentes funcionais do React por meio de ganchos?
Respostas:
Para a versão estável dos ganchos (React versão 16.8.0+)
Para componentDidMount
useEffect(() => {
// Your code here
}, []);
Para componentDidUpdate
useEffect(() => {
// Your code here
}, [yourDependency]);
Para componentWillUnmount
useEffect(() => {
// componentWillUnmount
return () => {
// Your code here
}
}, [yourDependency]);
Portanto, nesta situação, você precisa passar sua dependência para este array. Vamos supor que você tenha um estado como este
const [count, setCount] = useState(0);
E sempre que a contagem aumenta, você deseja renderizar novamente o componente de função. Então você useEffect
deve se parecer com isto
useEffect(() => {
// <div>{count}</div>
}, [count]);
Dessa forma, sempre que sua contagem for atualizada, seu componente será renderizado novamente. Espero que isso ajude um pouco.
useState
. Para quem undefined
estiver lendo isso, lembre-se de que deixar o segundo argumento fará com que seu efeito seja acionado em cada renderização (se não estou enganado).
Embora a resposta aceita funcione, não é recomendada. Quando você tem mais de um estado e o usa com useEffect, ele avisa sobre como adicioná-lo ao array de dependências ou não usá-lo.
Às vezes, causa problemas que podem gerar resultados imprevisíveis. Portanto, sugiro que você se esforce um pouco para reescrever sua função como classe. Existem muito poucas mudanças, e você pode ter alguns componentes como classe e alguns como função. Você não é obrigado a usar apenas uma convenção.
Veja isso por exemplo
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(...);
}
e
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(...);
}
Isso é apenas por exemplo . portanto, não vamos falar sobre as melhores práticas ou possíveis problemas com o código. Ambos têm a mesma lógica, mas o último funciona apenas conforme o esperado. Você pode obter a funcionalidade componentDidMount com useEffect em execução neste momento, mas conforme seu aplicativo cresce, há chances de que você possa enfrentar alguns problemas. Portanto, em vez de reescrever nessa fase, é melhor fazer isso no estágio inicial.
Além disso, OOP não é tão ruim assim, se a Programação Orientada a Procedimentos fosse suficiente, nunca teríamos tido a Programação Orientada a Objetos. É doloroso às vezes, mas melhor (tecnicamente. Questões pessoais à parte).
Não há componentDidMount
componentes funcionais, mas os Ganchos React fornecem uma maneira de emular o comportamento usando o useEffect
gancho.
Passe uma matriz vazia como o segundo argumento useEffect()
para executar apenas o retorno de chamada na montagem.
Por favor, leia a documentação emuseEffect
.
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>
Não há equivalente exato para componentDidMount
ganchos de reação.
Na minha experiência, os hooks react requerem uma mentalidade diferente ao desenvolvê-los e, de modo geral, você não deve compará-los aos métodos de classe como componentDidMount
.
Com isso dito, há maneiras de usar ganchos para produzir um efeito semelhante ao componentDidMount
.
Solução 1:
useEffect(() => {
console.log("I have been mounted")
}, [])
Solução 2:
const num = 5
useEffect(() => {
console.log("I will only run if my deps change: ", num)
}, [num])
Solução 3 (com função):
useEffect(() => {
const someFunc = () => {
console.log("Function being run after/on mount")
}
someFunc()
}, [])
Solução 4 (useCallback):
const msg = "some message"
const myFunc = useCallback(() => {
console.log(msg)
}, [msg])
useEffect(() => {
myFunc()
}, [myFunc])
Solução 5 (ser criativo):
export default function useDidMountHook(callback) {
const didMount = useRef(null)
useEffect(() => {
if (callback && !didMount.current) {
didMount.current = true
callback()
}
})
}
É importante notar que a solução 5 só deve ser usada realmente se nenhuma das outras soluções funcionar para seu caso de uso . Se você decidir que precisa da solução 5, recomendo usar este gancho pré-fabricado use-did-mount .
Fonte (com mais detalhes): Usando componentDidMount em react hooks
Você deseja usar useEffect()
, que, dependendo de como você usa a função, pode atuar como componentDidMount ().
Por exemplo. você pode usar uma loaded
propriedade de estado customizada que é inicialmente definida como false e alterná-la para true na renderização e apenas disparar o efeito quando esse valor mudar.