Nextjs — я слышал об этой платформе React для масштабируемых производственных приложений, и мне захотелось ее проверить! Я решил использовать контактное приложение, и, поскольку я узнаю что-то новое, почему бы не изучить и Tailwind. Так что вместо того, чтобы покупать один, почему бы не купить два по цене одного.
Немного не по теме, но One Piece — величайшее аниме всех времен!!!
Возвращаясь к тому, о чем я говорил, я здесь не для того, чтобы учить вас Nextjs, Tailwind или Flutter, я просто показываю вам, что я сделал, и надеюсь, вам это понравится. Давайте поймем несколько вещей:
Nextjs. Next.js — это гибкая инфраструктура React, которая дает вам строительные блоки для создания быстрых веб-приложений.
Prisma: Prisma помогает разработчикам приложений создавать быстрее и делать меньше ошибок с помощью набора инструментов баз данных с открытым исходным кодом для PostgreSQL, MySQL, SQL Server, SQLite. , MongoDB и CockroachDB.
SQLite: SQLite — это библиотека на языке C, которая реализует небольшой, быстрый, автономный, высоконадежный, полнофункциональный механизм базы данных SQL. . SQLite — самая используемая СУБД в мире. SQLite встроен во все мобильные телефоны и большинство компьютеров и входит в состав бесчисленного множества других приложений, которые люди используют каждый день.
Flutter: Flutter преобразует процесс разработки приложений. Создавайте, тестируйте и развертывайте красивые мобильные, веб-приложения, десктопные и встроенные приложения из единой кодовой базы.
Tailwind: Tailwind — быстро создавайте современные веб-сайты, не выходя из HTML-кода.
Теперь давайте погрузимся прямо в:
Это то, что мы будем строить; простое приложение для контактов, которое поможет вам: создать контакт, просмотреть его, обновить и удалить. Давайте создадим наши приложения:
Prisma хорошо интегрируется с Next.js. Next.js сочетает в себе внешний и внутренний код. Это означает, что мы можем создавать компоненты пользовательского интерфейса в Next.js, а также создавать маршруты API в том же приложении Next.js, поэтому Next.js содержит клиент и сервер. Prisma является соединением с базой данных, что делает его идеальным для вызова в нашем приложении Next.js для извлечения данных из серверной части для нас. В Next.js есть много способов получить данные. В Next.js есть три уникальные функции, которые мы можем использовать для получения данных для предварительного рендеринга, но я буду использовать только одну.
getServerSideProps (рендеринг на стороне сервера): запускается, когда страница предварительно обрабатывается при каждом запросе. Здесь мы также можем вызвать клиентские методы Prisma для получения данных, которые мы хотим передать компонентам Next.js.
npx create-next-app contactsapp //(creates the Nextjs App)
Переместитесь в папку: cd contactapp. Мы установим следующие зависимости:
npm install -D prisma //(add prisma) npm install @prisma/client //(Prisma client for JavaScript. It only runs on Node.js.)
Затем запустите:
npx prisma init
для инициализации Prisma и создания папки prisma внутри проекта contactapp и файла .env. Папка prisma будет содержать файл schema.prisma, здесь мы объявляем наши модели базы данных Prisma. Затем мы настраиваем соединения Prisma с нашей базой данных SQLite.
generator client { provider = "prisma-client-js" } datasource db { provider = "sqlite" url = "file:./dev.db" } model Contact { id String @id @default(cuid()) firstname String lastname String email String }
Это то, что у меня есть. Контакт — это модель, с которой мы работаем, вы можете добавить больше полей, если хотите. Затем вы запускаете миграции для создания таблицы:
npx prisma migrate dev
Теперь мы создадим наши компоненты -
components/AddScreen.js:
import { useForm } from 'react-hook-form'; const FormError = ({ errorMessage }) => { return <p className="text-red-300 mt-1">{errorMessage}</p>; }; const AddScreen = ({ contacts, AddContactFormProps }) => { const { register, handleSubmit, errors } = useForm(); console.log("The addCContact", AddContactFormProps); return ( <form className="flex flex-col" onSubmit={handleSubmit(AddContactFormProps)}> <div className="md:col-span-1 md:flex md:justify-start flex-col bg-slate-900 h-screen text-white px-3"> <h1 className="font-bold">Add a Contact</h1> <div> <div className="mb-4"> {/ <InputSpacer> /} <input className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="firstname" type="text" placeholder="firstname" name='firstname' {...register('firstname', { required: true })} /> {/* {errors.firstName && ( <FormError errorMessage="First Name is required" /> )} */} {/ </InputSpacer> /} </div> <div className="mb-4"> {/ <InputSpacer> /} <input className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="lastname" type="text" placeholder="lastname" name='lastname' {...register('lastname', { required: true })} /> {/* {errors.lastName && ( <FormError errorMessage="First Name is required" /> )} */} {/ </InputSpacer> /} </div> <div className="mb-4"> {/ <InputSpacer> /} <input className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="lastname" type="email" placeholder="email" name='email' {...register('email', { required: true })} /> {/* {errors.email && ( <FormError errorMessage="First Name is required" /> )} */} {/ </InputSpacer> /} </div> <div className=""> <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full" id="btnAdd" type="submit"> Add </button> </div> </div> {/ <Script src="/main.js" strategy='lazyOnload' /> /} </div> </form> ); } export default AddScreen;
components/DisplayScreen.js:
const DisplayScreen = ({ contacts, delContact }) => { console.log(contacts) return ( <div className="px-16 bg-gray-100 md:col-span-2 h-screen"> <h1 className="font-bold text-slate-800">All Contacts</h1> { contacts.map(contact => ( <div key={contact.id} className="bg-white rounded-md overflow-hidden shadow p-3 my-3 grid grid-cols-3 gap-3"> <div className="md:col-span-2"> <h1>{ contact.firstname } { contact.lastname }</h1> <span className="text-sm font-bold">{ contact.email }</span> </div> <div className="md:col-span-1"> <button className="bg-red-500 text-white p-2 rounded-md hover:scale-125 hover:opacity-80" onClick={ () => delContact(contact) }>Del</button> </div> </div> )) } </div> ); } export default DisplayScreen;
страницы/index.js:
import { PrismaClient } from '@prisma/client' import Head from 'next/head' import { useState } from 'react' import AddScreen from '../components/AddScreen' import DisplayScreen from '../components/DisplayScreen' const prisma = new PrismaClient() export const getServerSideProps = async () => { const contacts = await prisma.contact.findMany() return { props: { initialContacts: contacts } } } const saveContact = async (contact) => { const response = await fetch('/api/contacts', { method: 'POST', body: JSON.stringify(contact), headers: { 'Content-Type': 'application/json; charset=utf8' } }) console.log("response", contact) if (!response.ok) { throw new Error(response.statusText) } return await response.json() } const delContact = async (contact) => { if (window.confirm("Do you want to delete this food?")) { await fetch('/api/deleteContact', { method: 'POST', body: JSON.stringify({ id: contact.id }), headers: { 'Content-Type': 'application/json; charset=utf8' } }) // console.log("response", contact) } } export default function Home({ initialContacts }) { const [contacts, setContacts] = useState(initialContacts) return ( <div className=""> <Head> <title>Contact App</title> <meta name="description" content="Created by Connelblaze" /> <link rel="icon" href="/favicon.ico" /> </Head> <div className="grid md:grid-cols-3"> <AddScreen contacts = { initialContacts } AddContactFormProps = {async (data, e) => { try { await saveContact(data) setContacts([...contacts, data]) e.target.reset() } catch (error) { console.log(error); } }} /> <DisplayScreen contacts = { initialContacts } delContact = { delContact } /> </div> </div> ) }
Как видите, мы использовали Fetch для связи с API.
Маршруты API. Маршруты API в Next.js хранятся в папке pages/api. Каждый файл и папка сопоставляются с конечной точкой API. Они обслуживаются по тому же URL-адресу, что и внешний код, localhost:3000. Так как localhost:3000/getAllContacts возвращает страницу всех контактов из приложения Next.js.
Теперь вам нужно создать маршруты API.
страницы/api/getAllcontacts.js:
import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); export default async (req, res) => { const data = req.body; try { const result = await prisma.contact.findMany(); res.status(200).json(result); } catch (err) { console.log(err); res.status(403).json({ err: "Error occured." }); } }; This returns all contacts. pages/api/contacts.js: import { PrismaClient } from "@prisma/client" const prisma = new PrismaClient(); export default async function handler(req, res) { if (req.method !== 'POST') { return res.status(405).json({ message: 'Method not allowed' }); } try { const conatactData = req.body //JSON.parse(req.body); const saveContact = "Contacts "+ conatactData res.status(200).json(saveContact) } catch (err) { console.log("from API error", err) res.status(400).json({ message: 'Something went wrong' }); } }
Это удаляет контакт
Запустите это: npm run dev, и у вас должен быть работающий пример на: localhost:3000.
Теперь это ТУРФ!
Подождите, мне нужно перезарядиться, я имею в виду, что он работал без ошибок, я должен быть «Богом программирования»…
Ну это ложь! Я плакала, жалела о своем выборе, смотрела Youtube, заходила на Stackoverflow, и даже пришлось искать дискорд-канал Nextjs, чтобы все заработало… Никто не делится своими неудачами в сети…
Теперь все работает, давайте подключим сторону Flutter к нашему приложению Next.js.
Создайте новое приложение Flutter Кстати, я использовал VS Code для Next и Android Studio для Flutter. Я имею в виду, что хочу нагрузить свой ноутбук! Как я уже сказал, это на самом деле не учебник, я просто показываю вам, что я сделал, чтобы вы были впечатлены и бросили немного… или, может быть, нет, просто чтобы внести свой вклад в сообщество.
Теперь мне не нужно просматривать различные экраны, проверять Github и, пожалуйста, помечать: Flutter и Nextjs, я должен сказать следующее: localhost не будет работать, поэтому вам нужно получить IPv4 вашего компьютера и используйте его.
Так что да, я знаю, что не делал часть обновления, я имею в виду, что именно поэтому мы делаем открытый исходный код. Так почему бы не разветвить проект и не добавить это? Хм…
В любом случае, спасибо за чтение и просмотр, не забудьте поставить лайк и, возможно, поделиться!