fix: sync reactive state with data prop using \$effect
Replaces bare \$state(data.x) initialisers (which only capture the initial value) with \$state + \$effect pairs so that state stays in sync whenever page data is invalidated or the URL changes. Affects all list pages (searchValue) and all edit/detail pages (form fields). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
let deleteOpen = $state(false);
|
let deleteOpen = $state(false);
|
||||||
let deleting = $state(false);
|
let deleting = $state(false);
|
||||||
let searchValue = $state(data.search ?? "");
|
let searchValue = $state(data.search ?? "");
|
||||||
|
$effect(() => { searchValue = data.search ?? ""; });
|
||||||
let searchTimeout: ReturnType<typeof setTimeout>;
|
let searchTimeout: ReturnType<typeof setTimeout>;
|
||||||
|
|
||||||
function debounceSearch(value: string) {
|
function debounceSearch(value: string) {
|
||||||
|
|||||||
@@ -28,6 +28,20 @@
|
|||||||
);
|
);
|
||||||
let imageId = $state<string | null>(data.article.image ?? null);
|
let imageId = $state<string | null>(data.article.image ?? null);
|
||||||
let authorId = $state(data.article.author?.id ?? "");
|
let authorId = $state(data.article.author?.id ?? "");
|
||||||
|
$effect(() => {
|
||||||
|
title = data.article.title;
|
||||||
|
slug = data.article.slug;
|
||||||
|
excerpt = data.article.excerpt ?? "";
|
||||||
|
content = data.article.content ?? "";
|
||||||
|
category = data.article.category ?? "";
|
||||||
|
tags = data.article.tags ?? [];
|
||||||
|
featured = data.article.featured ?? false;
|
||||||
|
publishDate = data.article.publish_date
|
||||||
|
? new Date(data.article.publish_date).toISOString().slice(0, 16)
|
||||||
|
: "";
|
||||||
|
imageId = data.article.image ?? null;
|
||||||
|
authorId = data.article.author?.id ?? "";
|
||||||
|
});
|
||||||
let selectedAuthor = $derived(data.authors.find((a) => a.id === authorId) ?? null);
|
let selectedAuthor = $derived(data.authors.find((a) => a.id === authorId) ?? null);
|
||||||
let saving = $state(false);
|
let saving = $state(false);
|
||||||
let editorTab = $state<"write" | "preview">("write");
|
let editorTab = $state<"write" | "preview">("write");
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
let deleteOpen = $state(false);
|
let deleteOpen = $state(false);
|
||||||
let deleting = $state(false);
|
let deleting = $state(false);
|
||||||
let searchValue = $state(data.search ?? "");
|
let searchValue = $state(data.search ?? "");
|
||||||
|
$effect(() => { searchValue = data.search ?? ""; });
|
||||||
let searchTimeout: ReturnType<typeof setTimeout>;
|
let searchTimeout: ReturnType<typeof setTimeout>;
|
||||||
|
|
||||||
function debounceSearch(value: string) {
|
function debounceSearch(value: string) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
let deleteOpen = $state(false);
|
let deleteOpen = $state(false);
|
||||||
let deleting = $state(false);
|
let deleting = $state(false);
|
||||||
let searchValue = $state(data.search ?? "");
|
let searchValue = $state(data.search ?? "");
|
||||||
|
$effect(() => { searchValue = data.search ?? ""; });
|
||||||
let searchTimeout: ReturnType<typeof setTimeout>;
|
let searchTimeout: ReturnType<typeof setTimeout>;
|
||||||
|
|
||||||
function debounceSearch(value: string) {
|
function debounceSearch(value: string) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
const { data } = $props();
|
const { data } = $props();
|
||||||
|
|
||||||
let searchValue = $state(data.search ?? "");
|
let searchValue = $state(data.search ?? "");
|
||||||
|
$effect(() => { searchValue = data.search ?? ""; });
|
||||||
let searchTimeout: ReturnType<typeof setTimeout>;
|
let searchTimeout: ReturnType<typeof setTimeout>;
|
||||||
let deleteTarget: User | null = $state(null);
|
let deleteTarget: User | null = $state(null);
|
||||||
let deleteOpen = $state(false);
|
let deleteOpen = $state(false);
|
||||||
|
|||||||
@@ -24,6 +24,15 @@
|
|||||||
let photoId = $state<string | null>(data.user.photo ?? null);
|
let photoId = $state<string | null>(data.user.photo ?? null);
|
||||||
let isAdmin = $state(data.user.is_admin ?? false);
|
let isAdmin = $state(data.user.is_admin ?? false);
|
||||||
let saving = $state(false);
|
let saving = $state(false);
|
||||||
|
$effect(() => {
|
||||||
|
firstName = data.user.first_name ?? "";
|
||||||
|
lastName = data.user.last_name ?? "";
|
||||||
|
artistName = data.user.artist_name ?? "";
|
||||||
|
avatarId = data.user.avatar ?? null;
|
||||||
|
bannerId = data.user.banner ?? null;
|
||||||
|
photoId = data.user.photo ?? null;
|
||||||
|
isAdmin = data.user.is_admin ?? false;
|
||||||
|
});
|
||||||
|
|
||||||
async function handleAvatarUpload(files: File[]) {
|
async function handleAvatarUpload(files: File[]) {
|
||||||
const file = files[0];
|
const file = files[0];
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
let deleteOpen = $state(false);
|
let deleteOpen = $state(false);
|
||||||
let deleting = $state(false);
|
let deleting = $state(false);
|
||||||
let searchValue = $state(data.search ?? "");
|
let searchValue = $state(data.search ?? "");
|
||||||
|
$effect(() => { searchValue = data.search ?? ""; });
|
||||||
let searchTimeout: ReturnType<typeof setTimeout>;
|
let searchTimeout: ReturnType<typeof setTimeout>;
|
||||||
|
|
||||||
function debounceSearch(value: string) {
|
function debounceSearch(value: string) {
|
||||||
|
|||||||
@@ -29,6 +29,20 @@
|
|||||||
let selectedModelIds = $state<string[]>(
|
let selectedModelIds = $state<string[]>(
|
||||||
data.video.models?.map((m: { id: string }) => m.id) ?? [],
|
data.video.models?.map((m: { id: string }) => m.id) ?? [],
|
||||||
);
|
);
|
||||||
|
$effect(() => {
|
||||||
|
title = data.video.title;
|
||||||
|
slug = data.video.slug;
|
||||||
|
description = data.video.description ?? "";
|
||||||
|
tags = data.video.tags ?? [];
|
||||||
|
premium = data.video.premium ?? false;
|
||||||
|
featured = data.video.featured ?? false;
|
||||||
|
uploadDate = data.video.upload_date
|
||||||
|
? new Date(data.video.upload_date).toISOString().slice(0, 16)
|
||||||
|
: "";
|
||||||
|
imageId = data.video.image ?? null;
|
||||||
|
movieId = data.video.movie ?? null;
|
||||||
|
selectedModelIds = data.video.models?.map((m: { id: string }) => m.id) ?? [];
|
||||||
|
});
|
||||||
let saving = $state(false);
|
let saving = $state(false);
|
||||||
|
|
||||||
async function handleImageUpload(files: File[]) {
|
async function handleImageUpload(files: File[]) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
const { data } = $props();
|
const { data } = $props();
|
||||||
|
|
||||||
let searchValue = $state(data.search ?? "");
|
let searchValue = $state(data.search ?? "");
|
||||||
|
$effect(() => { searchValue = data.search ?? ""; });
|
||||||
let searchTimeout: ReturnType<typeof setTimeout>;
|
let searchTimeout: ReturnType<typeof setTimeout>;
|
||||||
|
|
||||||
const featuredArticle =
|
const featuredArticle =
|
||||||
|
|||||||
@@ -39,6 +39,15 @@
|
|||||||
let artistName = $state(data.authStatus.user!.artist_name);
|
let artistName = $state(data.authStatus.user!.artist_name);
|
||||||
let description = $state(data.authStatus.user!.description);
|
let description = $state(data.authStatus.user!.description);
|
||||||
let tags = $state(data.authStatus.user!.tags ?? undefined);
|
let tags = $state(data.authStatus.user!.tags ?? undefined);
|
||||||
|
$effect(() => {
|
||||||
|
recordings = data.recordings;
|
||||||
|
firstName = data.authStatus.user!.first_name;
|
||||||
|
lastName = data.authStatus.user!.last_name;
|
||||||
|
artistName = data.authStatus.user!.artist_name;
|
||||||
|
description = data.authStatus.user!.description;
|
||||||
|
tags = data.authStatus.user!.tags ?? undefined;
|
||||||
|
email = data.authStatus.user!.email;
|
||||||
|
});
|
||||||
|
|
||||||
let email = $state(data.authStatus.user!.email);
|
let email = $state(data.authStatus.user!.email);
|
||||||
let password = $state("");
|
let password = $state("");
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
const { data } = $props();
|
const { data } = $props();
|
||||||
|
|
||||||
let searchValue = $state(data.search ?? "");
|
let searchValue = $state(data.search ?? "");
|
||||||
|
$effect(() => { searchValue = data.search ?? ""; });
|
||||||
let searchTimeout: ReturnType<typeof setTimeout>;
|
let searchTimeout: ReturnType<typeof setTimeout>;
|
||||||
|
|
||||||
function debounceSearch(value: string) {
|
function debounceSearch(value: string) {
|
||||||
|
|||||||
@@ -18,6 +18,9 @@
|
|||||||
const { data } = $props();
|
const { data } = $props();
|
||||||
|
|
||||||
let searchValue = $state(data.search ?? "");
|
let searchValue = $state(data.search ?? "");
|
||||||
|
$effect(() => {
|
||||||
|
searchValue = data.search ?? "";
|
||||||
|
});
|
||||||
let searchTimeout: ReturnType<typeof setTimeout>;
|
let searchTimeout: ReturnType<typeof setTimeout>;
|
||||||
|
|
||||||
function debounceSearch(value: string) {
|
function debounceSearch(value: string) {
|
||||||
|
|||||||
@@ -30,6 +30,10 @@
|
|||||||
const timeAgo = new TimeAgo("en");
|
const timeAgo = new TimeAgo("en");
|
||||||
let isLiked = $state(data.likeStatus.liked);
|
let isLiked = $state(data.likeStatus.liked);
|
||||||
let likesCount = $state(data.video.likes_count || 0);
|
let likesCount = $state(data.video.likes_count || 0);
|
||||||
|
$effect(() => {
|
||||||
|
isLiked = data.likeStatus.liked;
|
||||||
|
likesCount = data.video.likes_count || 0;
|
||||||
|
});
|
||||||
let isLikeLoading = $state(false);
|
let isLikeLoading = $state(false);
|
||||||
let newComment = $state("");
|
let newComment = $state("");
|
||||||
let showComments = $state(true);
|
let showComments = $state(true);
|
||||||
|
|||||||
Reference in New Issue
Block a user