Me gustaría hacer un componente en SvelteKit que tenga un parámetro aleatorio. El problema es que el valor que toma este parámetro es diferente cuando la página se procesa en el lado del servidor y cuando esa página se hidrata.
Por ejemplo, considere este componente:
<script> export let t = Math.random() * 90 export let l = Math.random() * 90 </script> <div class="box" style="--t: {t}vh; --l: {l}vw;"></div> <style> .box { position: fixed; top: var(--t); left: var(--l); width: 10vw; height: 10vh; background-color: black; transition: all 1s; } </style> Cuando la página se representa en el servidor, t y l toman un valor aleatorio y el resultado se devuelve al navegador como HTML. Sin embargo, una vez que la página se hidrata, t y l toman valores diferentes. Como resultado, la caja se mueve.
No quiero que la caja se mueva; más bien, quiero que el cliente también use el valor aleatorio devuelto por el servidor para que no haya un cambio de estilo. Todo está bien si la página se navega a través del enrutador en la página; es cuando la página se procesa en el servidor que la caja se mueve.
El resultado es el mismo si exporto una función de load . ¿Hay alguna manera con SvelteKit para que el servidor y el cliente acuerden un valor aleatorio?
Tienes algunas opciones aquí:
<script> import { onMount } from 'svelte'; let t, l; onMount(() => { t = Math.random() * 90; l = Math.random() * 90; }) </script> {#if t && l } <div class="box" style="--t: {t}vh; --l: {l}vw;"></div> {/if} <style> .box { position: fixed; top: var(--t); left: var(--l); width: 10vw; height: 10vh; background-color: black; transition: all 1s; } </style> // random.json.js export async function get() { return { body: { t: Math.random() * 90, l: Math.random() * 90, }, }; } <!-- index.svelte --> <script context="module"> export async function load({ fetch }) { // this will be cached, so it will be the same on client & server const result = await fetch('/random.json'); const { t, l } = await result.json(); return { props: { t, l } } } </script> <script> export let t; export let l; </script> <div class="box" style="--t: {t}vh; --l: {l}vw;"></div> <style> .box { position: fixed; top: var(--t); left: var(--l); width: 10vw; height: 10vh; background-color: black; transition: all 1s; } </style>Personalmente, me gusta más la segunda opción, ya que no hay FOUC.
Creo que podría evitar una llamada de back-end y usar un generador de números pseudoaleatorios predecible.
Por ejemplo; https://github.com/davidbau/seedrandom