Вопрос
Возможно ли реализовать Custom React Hook, который будет создавать простой класс JS только на клиенте в Next js?
Причина может быть только создание экземпляра в клиенте происходит потому, что простой класс JS использует sessionStorage, который НЕ доступен на следующем js сервере.
Кажется, что изящная реализация будет одной из следующих:
- Создайте его внутри
useEffect
, поскольку он запускается только на клиенте - Создайте его внутри Custom Hook, чтобы функциональность могла быть разделена между компонентами.
Примечание: I у меня нет четкой мысленной модели шагов, которые React предпринимают с регидратацией / рендерингом с использованием SSR, поэтому исправьте меня, если мое объяснение неверно.
Ссылки:
Классы
CheckoutStorage
- обычный JS класс Address
- компонент использует CheckoutStorage
Создайте его внутри пользовательский хук
// A simple class to retrive data from Session Storage.
class CheckoutStorage {
constructor() {
this._address = JSON.parse(sessionStorage.getItem('selectedAddress'))
// ...other class attributes...
}
get address() {
return this._address
}
// prefer function setters instead of having to do "checkoutStorage = something"
setAddress(address) {
sessionStorage.setItem('selectedAddress', address)
this._address = address
}
// ...other functions...
}
export default CheckoutStorage
Address
(компонент функции) с использованием пользовательского хука
компонента, который будет использовать CheckoutStorage
// Custom hook that will return an instantiated CheckoutStorage class on client.
const useCheckoutStorage = () => {
const [checkoutStorage, setCheckoutStorage] = useState(null)
useEffect(() => {
setCheckoutStorage(new CheckoutStorage())
}, [])
return checkoutStorage
}
const Address = () => {
// ..other code..
// Defined at the top of the component so other functions can use it.
const checkoutStorage = useCheckoutStorage()
const [addresses, setAddresses] = useState([])
const [selectedAddressId, setSelectedAddressId] = useState(-1)
useEffect(() => {
// Function that makes API call and calls `setAddresses(..)`
fetchAddresses()
// Get previously selected address ID in session storage
setSelectedAddressId(checkoutStorage.address.id)
}, [])
// other code...
return (
<div>...<div>
)
}
ошибка
Unable to find 'address' of undefined
Это относится к строке:
setSelectedAddressId(checkoutStorage.address.id)
- Мы используем
checkoutStorage
внутри useEffect()
- На данный момент в время,
useCheckoutStorage
вернет ноль, поскольку его эффект не был выполнен. - Он вернет только экземпляр класса CheckoutStorage после установки состояния в
fetchAdddresses()
Рабочая версия Address
создание экземпляров внутри useEffect()
const Address = () => {
// ..other code..
// Previous try with a custom hook
// const checkoutStorage = useCheckoutStorage()
const [checkoutStorage, setCheckoutStorage] = useState(null)
const [addresses, setAddresses] = useState([])
const [selectedAddressId, setSelectedAddressId] = useState(-1)
useEffect(() => {
// Added the immediate 2 lines
const checkoutStorage = new CheckoutStorage()
setCheckoutStorage(checkoutStorage)
// Function that makes API call and calls `setAddresses(..)`
fetchAddresses()
// Get previously selected address ID in session storage
setSelectedAddressId(checkoutStorage.address.id)
}, [])
// other code...
return (
<div>...<div>
)
}
Вышеописанная реализация работает, однако, если я хотел бы использовать checkoutStorage
в другом компоненте, мне нужно было бы сделать что-то подобное.
Итак, вернемся к вопросу:
Возможно ли реализовать Custom React Hook, который будет создавать простой класс JS только на клиенте в Next js?
Если нет, делает ли эта реализация имеет смысл?
Заранее спасибо!
Оставайтесь в безопасности. Остаться дома. Оставайтесь на StackFlow.