Saya sedang mengusahakan buku David Lorenz Membina Aplikasi Web Gred Pengeluaran dengan Supabase (pautan gabungan) dan baru sahaja selesai Bab 3 – Mencipta Halaman Pengurusan Tiket…. Saya telah menghadapi beberapa isu dan terfikir untuk berkongsi isu tersebut bersama-sama cara saya membetulkannya.
Anda boleh mengabaikan pageProps.children dan meninggalkannya sebagai kanak-kanak.
Walaupun Lorenz dengan jelas menyatakan:
Jadi, buka app/page.js dan tukar komponen Halaman supaya ia hanya akan mengembalikan komponen Log Masuk buat masa ini...
Saya masih perlu pergi mencari sendiri apabila saya menemui arahan untuk mengedit Halaman Masuk. Saya mengharapkan kami membuat halaman baharu dan bukannya menggunakan page.js sedia ada, tetapi tidak, padamkan semuanya dalam page.js dan tampalkan kod Halaman Masuk sahaja seperti yang diberikan dalam buku.
Setelah kami mengemas kini apl/Login.js dengan logik togol (untuk menghidupkan/mematikan medan kata laluan) kami mula melihat ralat ini:
Error: Route "/" used `searchParams.magicLink`. `searchParams` should be awaited before using its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis at LoginPage (src/app/page.js:3:38) 1 | import { Login } from "./Login"; 2 | export default function LoginPage({ searchParams }) { > 3 | const wantsMagicLink = searchParams.magicLink === "yes"; | ^ 4 | return <login ispasswordlogin="{!wantsMagicLink}"></login>; 5 | }
Untuk membetulkannya, kami mahu menjadikan fungsi Halaman Masuk dalam app/page.js tidak segerak seperti:
import { Login } from "./Login"; export default async function LoginPage({ searchParams }) { const params = await searchParams; const wantsMagicLink = params.magicLink === "yes"; return <login ispasswordlogin="{!wantsMagicLink}"></login>; }
Dalam buku kami diarahkan untuk mengemas kini kod kami dalam Login.js seperti:
"use client"; import { useRef } from "react"; export const Login = () => { const emailInputRef = useRef(null); const passwordInputRef = useRef(null); return ( ... ) }Salin selepas log masukSalin selepas log masuk
Sekiranya ini tidak sepenuhnya jelas, berikut ialah rupa kod anda:
"use client"; import { useRef } from "react"; import Link from "next/link"; export const Login = ({ isPasswordLogin }) => { const emailInputRef = useRef(null); const passwordInputRef = useRef(null); return( ... ) }
Di mana ... kami tidak mengubah apa-apa. Pada asasnya, segala-galanya daripada pemulangan( pada tetap sama seperti sebelumnya.
"Perkara besar" yang saya nyatakan di atas ialah seseorang itu tidak seharusnya mengalih keluar Pautan import daripada "seterusnya/pautan"; sebaliknya tambah "gunakan klien"; dan import useRef sebelum itu.
Nota sampingan: Mungkin kita akan belajar kemudian, tetapi saya rasa agak pelik untuk menggunakan useRef dan bukannya useState di sini, tetapi sekali lagi, saya bukan pakar Next.js atau React.
Dalam Login.js dalam pemulangan( ... ), gantikan
Dalam kod untuk app/tickets/TenantName.js Lorenz menggunakan ex unit CSS yang jarang digunakan:
<strong> </strong>Salin selepas log masuk
I suspect that this is actually a typo and that Lorenz intended for this to be 1em. While ex is a valid CSS unit it is rarely utilized and is based on the height of the current font. For more on this topic see:
For those who aren’t familiar with React the instruction to add dummyTickets to the page.js file may not be clear enough. You’ll want put these in the TicketListPage() function before the return.
Lorenz instructs us to import the TicketList component into page.js. This is pretty straightforward but may be helpful to note that since this is a “named export” we want our import in page.js to look like:
import { TicketList } from "./TicketList";
Dan bukan seperti:
import TicketList from "./TicketList";
Jika anda melakukan yang terakhir, anda akan mendapat salah satu daripada mesej ralat yang menggemari:
Error: Route "/" used `searchParams.magicLink`. `searchParams` should be awaited before using its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis at LoginPage (src/app/page.js:3:38) 1 | import { Login } from "./Login"; 2 | export default function LoginPage({ searchParams }) { > 3 | const wantsMagicLink = searchParams.magicLink === "yes"; | ^ 4 | return <login ispasswordlogin="{!wantsMagicLink}"></login>; 5 | }Salin selepas log masukSalin selepas log masukSalin selepas log masuk
Apabila kami mengikuti arahan untuk mencipta fungsi TicketDetailsPage, kami akan melihat ralat berikut:
import { Login } from "./Login"; export default async function LoginPage({ searchParams }) { const params = await searchParams; const wantsMagicLink = params.magicLink === "yes"; return <login ispasswordlogin="{!wantsMagicLink}"></login>; }
Anda mungkin masih ingat bahawa kami telah melihat ralat serupa sebelum ini dengan fungsi LoginPage dan kami menyelesaikannya dengan menjadikan fungsi kami tidak segerak dan menunggu parameter. Kami akan melakukan perkara yang sama di sini:
"use client"; import { useRef } from "react"; export const Login = () => { const emailInputRef = useRef(null); const passwordInputRef = useRef(null); return ( ... ) }
Selepas mengemas kini fail /tickets/details/[id]/page.js (fungsi TicketDetailsPage) kami mendapat ralat yang hampir sama seperti yang kami lakukan di bahagian terakhir. Apa yang memberiMembina Aplikasi Web Gred Pengeluaran dengan Supabase – Bahagian 2 Mudah, kami mengemas kini kod kami di bahagian terakhir tetapi buku itu tidak mengetahuinya, jadi buku itu masih menggunakan params.id, cuma gantikan params.id dengan id dan semuanya sepatutnya seperti hujan.
Laluan untuk fail ulasan baharu hendaklah /tickets/details/[id]/TicketComments.js dan bukan /tickets/details[id]/TicketComments.js.
Walaupun Next.js tidak membuang sebarang ralat dalam output terminal selepas menambah kod yang memaparkan ulasan sebenar pada TicketComments.js, anda akan melihat satu dalam penyemak imbas:
"use client"; import { useRef } from "react"; import Link from "next/link"; export const Login = ({ isPasswordLogin }) => { const emailInputRef = useRef(null); const passwordInputRef = useRef(null); return( ... ) }Salin selepas log masukSalin selepas log masuk
Terdapat dua sebab ini berlaku. Yang pertama ialah kami sebenarnya tidak menggunakan tarikh sebagai kunci, kerana kami mempunyai petikan sekitar {comment.date} yang kami hantar dalam rentetan literal comment.date. Untuk membetulkannya, kita perlu mengalih keluar petikan supaya ini:
I suspect that this is actually a typo and that Lorenz intended for this to be 1em. While ex is a valid CSS unit it is rarely utilized and is based on the height of the current font. For more on this topic see:
- W3’s Example Page for EM, PX, PT, CM, IN…
- W3School’s CSS Units.
- Perplexity: Should one use the ex CSS unitMembina Aplikasi Web Gred Pengeluaran dengan Supabase – Bahagian 2
Subsection: Designing the Ticket List Page
Creating dummy tickets whereMembina Aplikasi Web Gred Pengeluaran dengan Supabase – Bahagian 2
For those who aren’t familiar with React the instruction to add dummyTickets to the page.js file may not be clear enough. You’ll want put these in the TicketListPage() function before the return.
Import howMembina Aplikasi Web Gred Pengeluaran dengan Supabase – Bahagian 2
Lorenz instructs us to import the TicketList component into page.js. This is pretty straightforward but may be helpful to note that since this is a “named export” we want our import in page.js to look like:
import { TicketList } from "./TicketList";Salin selepas log masukDigantikan dengan:
import TicketList from "./TicketList";Salin selepas log masukSalin selepas log masukSetelah ini dilakukan, kami tidak akan mendapat ralat itu lagi tetapi kami harus ambil perhatian bahawa terdapat isu lain, walaupun ia tidak nyata pada masa ini. Apakah yang berlaku jika dua atau lebih individu mengulas pada tarikh yang samaMembina Aplikasi Web Gred Pengeluaran dengan Supabase – Bahagian 2 Kekunci kami sekali lagi tidak unik dan kami akan melihat ralat yang sama ini. Kami boleh membetulkannya dengan cepat dengan menambahkan sifat id pada ulasan kami. Komen kami yang dikemas kini sepatutnya kelihatan seperti:
./src/app/tickets/page.js:1:1 Export default doesn't exist in target module 1 | import TicketList from "./TicketList"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | 3 | export default function TicketListPage() { 4 | const dummyTickets = [ The export default was not found in module [project]/src/app/tickets/TicketList.js [app-rsc] (ecmascript). Did you mean to import TicketListMembina Aplikasi Web Gred Pengeluaran dengan Supabase – Bahagian 2 All exports of the module are statically known (It doesn't have dynamic exports). So it's known statically that the requested export doesn't exist.Salin selepas log masukMaka kita hanya perlu menukar:
Error: Route "/tickets/details/[id]" used `params.id`. `params` should be awaited before using its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis at TicketDetailsPage (src/app/tickets/details/[id]/page.js:4:50) 2 | return ( 3 | <div> > 4 | Ticket Details page with <strong>ID={params.id}</strong> | ^ 5 | </div> 6 | ); 7 | }Salin selepas log masukKepada:
export default async function TicketDetailsPage({ params }) { const ticketParams = await params; const id = ticketParams.id; return ( <div> Ticket Details page with <strong>ID={id}</strong> </div> ); }Salin selepas log masukSubseksyen: Melaksanakan halaman untuk membuat tiket baharu
Tiada apa yang boleh dilihat di sini.
Subseksyen: Melaksanakan gambaran keseluruhan pengguna
Memasang Ikon
Kita perlu memasang pakej @tabler/icons-react: npm i @tabler/icons-react
Semasa Lorenz menggunakan IconCheck, saya akan mengesyorkan menggunakan IconUserCheck kerana ia lebih jelas sedikit perkara yang dipaparkan.
Kami perlu mengimport komponen IconUserCheck dan IconUserOff dalam pengguna/page.js kami:
Encountered two children with the same key, `{comment.date}`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.Salin selepas log masukDan kita perlu menggantikan:
<article key="{comment.date}"> </article>Salin selepas log masukDengan:
Error: Route "/" used `searchParams.magicLink`. `searchParams` should be awaited before using its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis at LoginPage (src/app/page.js:3:38) 1 | import { Login } from "./Login"; 2 | export default function LoginPage({ searchParams }) { > 3 | const wantsMagicLink = searchParams.magicLink === "yes"; | ^ 4 | return <login ispasswordlogin="{!wantsMagicLink}"></login>; 5 | }Salin selepas log masukSalin selepas log masukSalin selepas log masukTukar nama laluan === "/tickets" ke mana-mana halaman yang dituju oleh pautan, mis. jika pautan menghala ke /tickets/new maka anda harus menetapkan bahagian nama laluan kepada nama laluan === "/tickets/new".
Kesimpulannya
Tahniah, anda kini orang #3 yang berminat dengan siaran ini.
Atas ialah kandungan terperinci Membina Aplikasi Web Gred Pengeluaran dengan Supabase – Bahagian 2. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!