javascript - Converting componentDidMount into useEffect
问题描述
I am trying to learn React hooks, and trying to convert existing codebase to use hooks, but I am confused.
Is it normal to set state inside useEffect
? Would I be causing the dreaded infinite loop if I do so?
import React, { useState, useEffect } from 'react';
import App from 'next/app';
import Layout from './../components/Layout';
function MyApp({ Component, pageProps }) {
const [ cart, setCart ] = useState([]);
const addToCart = (product) => {
setCart((prevCartState) => {
return [ ...prevCartState, product ];
});
localStorage.setItem('cart', JSON.stringify(cart));
};
//mimicking componentDidMount to run some effect using useEffect
//useEffect(() => setCount((currentCount) => currentCount + 1), []);
useEffect(() => {
const cartCache = JSON.parse(localStorage.getItem('cart'));
//cart = cartCache; Good or bad?
cartCache || setCart(() =>{
});
}, []);
return <Component {...pageProps} />;
}
My original class based component:
/*
export default class MyApp extends App {
state = {
cart: []
}
componentDidMount = () => {
const cart = JSON.parse(localStorage.getItem('cart'));
if (cart) {
this.setState({
cart
});
}
};
addToCart = (product) => {
this.setState({
cart: [...this.state.cart, product]
});
localStorage.setItem('cart', JSON.stringify(this.state.cart));
}
render() {
const { Component, pageProps } = this.props
return (
<contextCart.Provider value={{ cart: this.state.cart, addToCart: this.addToCart }}>
<Layout>
<Component {...pageProps} />
</Layout>
</contextCart.Provider>
)
}
}*/
解决方案
It's okey to set state inside useEffect
as long as you don't listen to changes of the same field inside dependency array. In your particular case you are calling useEffect
only once (since you have passed an empty dependency array).
useEffect(() => {
const cartCache = JSON.parse(localStorage.getItem('cart'));
if (cartCache) {
setCart(cartCache);
}
}, []);
Also would be cool to add the second useEffect
to listen to cart
changes and keep the localStorage
up-to-date.
useEffect(() => {
localStorage.setItem('cart', JSON.stringify(cart));
}, [cart]);
推荐阅读
- python - Pandas dtypes.to_dict 给出了太多的值来解包
- php - 如何将@foreach 值传递给 Bootstrap 模式?拉拉维尔 7.3
- react-native - 将您的代码从 `jumpToIndex(2)` 更改为 `jumpTo('')。
- javascript - 如何添加在每个级别完成后重置的计时器?
- ios - 如何将数据存储给所有用户?
- p5.js - 为什么我的 For() 循环动画不起作用?
- aurelia - 如何在 aurelia js 中将状态设置为 oidc-client-js
- javascript - Javascript 2D 数组意外行为
- random - 在 Pytorch 上重置随机初始化
- ios - 了解 ASAuthorizationPasswordProvider