使用react进行用户管理系统
今天通了一遍使用react进行用户管理系统的文档,以及跟随步骤实现了一遍,我大概梳理一下实现思路。
首先我们构建基本用户管理应用,需要数据库存储个人资料,我们先去supabase注册然后创建自己的数据库然后设置密码,然后去sql editor找到模板,user management starter创建一个空表profiles,这时候我们有了我们自己的数据库以及数据表,当然我们在创建表的时候也创建了相关的后端逻辑,也就是说supabase是一个自带后端的数据库,平台帮你一键搞定数据库、认证、权限、安全等基础设施,我们只需要调用平台接口,关注业务逻辑和前端开发。然后我们需要把官网创建的云端数据库拉取到本地,首先呢我们需要npm install -g supabase安装 Supabase CLI工具,它可以初始化本地 Supabase 项目(supabase init)关联本地和云端项目(supabase link)拉取云端数据库结构(supabase db pull)本地启动 Supabase 开发环境(supabase start)等等。
然后下载完工具后,我们初始化本地supabase项目,也就是supabase init,然后我们需要登录supabase cli,让cil工具识别我们我们才可以supabase link执行这个把项目拉取到本地,这时候密码输入就算本地supabase和线上数据库连接了,然后supabase db pull拉取到本地supabase项目,我们就算是把云端的数据库表结构拿了过来。表结构包括表,函数,以及后端策略。
然后我们创建react模板的vite项目,新建.env.local文件引入数据库的url和anon key然后新建supabase.js我们引入supabase-js库然后加入代码
import { createClient } from '@supabase/supabase-js'const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEYexport const supabase = createClient(supabaseUrl, supabaseAnonKey)
我们就相当于项目和数据库完全的连接了并且可以直接使用supabase-js里面的方法api以及后端逻辑。
那么剩下的步骤就是开发也就是写代码了。
这里我就都不写出来了我只写登入以及信息页面的代码。
import { useState } from 'react'import { supabase } from './supabaseClient'export default function Auth() {const [loading, setLoading] = useState(false)const [email, setEmail] = useState('')const handleLogin = async (event) => {event.preventDefault()setLoading(true)const { error } = await supabase.auth.signInWithOtp({ email })if (error) {alert(error.error_description || error.message)} else {alert('Check your email for the login link!')}setLoading(false)}return (<div className="row flex flex-center"><div className="col-6 form-widget"><h1 className="header">Supabase + React</h1><p className="description">Sign in via magic link with your email below</p><form className="form-widget" onSubmit={handleLogin}><div><inputclassName="inputField"type="email"placeholder="Your email"value={email}required={true}onChange={(e) => setEmail(e.target.value)}/></div><div><button className={'button block'} disabled={loading}>{loading ? <span>Loading</span> : <span>Send magic link</span>}</button></div></form></div></div>)}
这是登录页面,下面是个人信息页面
import { useState, useEffect } from 'react'
import { supabase } from './supabaseClient'
export default function Account({ session }) {
const [loading, setLoading] = useState(true)
const [username, setUsername] = useState(null)
const [website, setWebsite] = useState(null)
const [avatar_url, setAvatarUrl] = useState(null)
useEffect(() => {
let ignore = false
async function getProfile() {
setLoading(true)
const { user } = session
const { data, error } = await supabase
.from('profiles')
.select(username, website, avatar_url)
.eq('id', user.id)
.single()
if (!ignore) {
if (error) {
console.warn(error)
} else if (data) {
setUsername(data.username)
setWebsite(data.website)
setAvatarUrl(data.avatar_url)
}
}
setLoading(false)
}
getProfile()
return () => {
ignore = true
}
}, [session])
async function updateProfile(event, avatarUrl) {
event.preventDefault()
setLoading(true)
const { user } = session
const updates = {
id: user.id,
username,
website,
avatar_url: avatarUrl,
updated_at: new Date(),
}
const { error } = await supabase.from('profiles').upsert(updates)
if (error) {
alert(error.message)
} else {
setAvatarUrl(avatarUrl)
}
setLoading(false)
}
return (
<form onSubmit={updateProfile} className="form-widget">
<div>
<label htmlFor="email">Email</label>
<input id="email" type="text" value={session.user.email} disabled />
</div>
<div>
<label htmlFor="username">Name</label>
<input
id="username"
type="text"
required
value={username || ''}
onChange={(e) => setUsername(e.target.value)}
/>
</div>
<div>
<label htmlFor="website">Website</label>
<input
id="website"
type="url"
value={website || ''}
onChange={(e) => setWebsite(e.target.value)}
/>
</div>
<div>
<button className="button block primary" type="submit" disabled={loading}>
{loading ? 'Loading ...' : 'Update'}
</button>
</div>
<div>
<button className="button block" type="button" onClick={() => supabase.auth.signOut()}>
Sign Out
</button>
</div>
</form>
)
}
以及app页面
import './App.css'
import { useState, useEffect } from 'react'
import { supabase } from './supabaseClient'
import Auth from './Auth'
import Account from './Account'
function App() {
const [session, setSession] = useState(null)
useEffect(() => {
supabase.auth.getSession().then(({ data: { session } }) => {
setSession(session)
})
supabase.auth.onAuthStateChange((_event, session) => {
setSession(session)
})
}, [])
return (
<div className="container" style={{ padding: '50px 0 100px 0' }}>
{!session ? <Auth /> : <Account key={session.user.id} session={session} />}
</div>
)
}
export default App
现在我们总结一下思路,登录页面auth.jsx,关键是 await supabase.auth.signInWithOtp({ email })这个supabase自带的otp登录api,实现用户通过邮箱验收验证码的方式登录,无需密码,然后onChange={(e) => setEmail(e.target.value)}监听输入框内的内容,把内容存入状态,提交就可以了。
登录成功后session会返回,我们在app根组件中监听用supabase.auth.onAutnStateChange 来监听获取session,通过session是否返回也就是是否登录来判断渲染登录页还是账户页面
然后再账户页面,核心就是
const { data, error } = await supabase.from('profiles').select(username, website, avatar_url).eq('id', user.id).single()
使用useEffect在账户页面加载从profiles表中读取当前用户的username,website,avataer.url然后通过表单输入框 onchange监听实时更新username和website的值,点击更新按钮触发updataProfile函数调用await supabase.from('profiles').upsert(updates)更新数据库。
ok大概这就是核心思路,扩展的上传头像框可以去对应的文档练习,我觉得关键的思路这些已经齐全了,大家可以评论指点我一下,谢谢大家。
相关文章:
使用react进行用户管理系统
今天通了一遍使用react进行用户管理系统的文档,以及跟随步骤实现了一遍,我大概梳理一下实现思路。 首先我们构建基本用户管理应用,需要数据库存储个人资料,我们先去supabase注册然后创建自己的数据库然后设置密码,然后…...
SpringBoot的java应用中,慢sql会导致CPU暴增吗
是的,在 Spring Boot 的 Java 应用中,慢 SQL 同样可能导致 CPU 暴增。虽然数据库服务器的 CPU 通常是主要压力点,但应用服务器(Java 进程)的 CPU 也可能间接受到影响,具体原因和机制如下: 1. 数…...

Ubuntu下编译mininim游戏全攻略
目录 一、安装mininim 软件所依赖的库(重点是allegro游戏引擎库)二、编译mininim 软件三、将mininim打包给另一个Ubuntu系统使用四、安卓手机运行mininim 一、安装mininim 软件所依赖的库(重点是allegro游戏引擎库) 1. 用apt-get…...

uniapp uni-id Error: Invalid password secret
common文件夹下uni-config-center文件夹下新建uni-id,新建config.json文件 复制粘贴以下代码,不要自己改,格式容易错 {"passwordSecret": [{"type": "hmac-sha256","version": 1}], "passwordStrength&qu…...
用 Appuploader,让 iOS 上架流程真正“可交接、可记录、可复用”:我们是这样实现的
你可能听说过这样一类人:上线必找他,证书只有他有,Transporter 密码在他电脑上,描述文件什么时候过期,只有他知道。 如果你团队里有这样一位“发布大师”,他可能是个英雄——但也是个单点风险源。 我们团…...

第十二节:第三部分:集合框架:List系列集合:特点、方法、遍历方式、ArrayList集合的底层原理
List系列集合特点 List集合的特有方法 List集合支持的遍历方式 ArrayList集合的底层原理 ArrayList集合适合的应用场景 代码:List系列集合遍历方式 package com.itheima.day19_Collection_List;import java.util.ArrayList; import java.util.Iterator; import jav…...

【办公类-18-07】20250527屈光检查PDF文件拆分成多个pdf(两页一份,用幼儿班级姓名命名文件)
背景需求: 今天春游,上海海昌公园。路上保健老师收到前几天幼儿的屈光视力检查单PDF。 她说:所有孩子的通知都做在一个PDF里,我没法单独发给班主任。你有什么办法拆开来? 我说:“没问题,问deep…...

AI Agent的“搜索大脑“进化史:从Google API到智能搜索生态的技术变革
AI Agent搜索革命的时代背景 2025年agent速度发展之快似乎正在验证"2025年是agent元年"的说法,而作为agent最主要的应用工具之一(另外一个是coding),搜索工具也正在呈现快速的发展趋势。Google在2024年12月推出Gemini Deep Research࿰…...

Arduino学习-跑马灯
1、效果 2、代码 /**** 2025-5-30 跑马灯的小程序 */ //时间间隔 int intervaltime200; //初始化函数 void setup() {// put your setup code here, to run once://设置第3-第7个引脚为输出模式for(int i3;i<8;i){pinMode(i,OUTPUT);} }//循环执行 void loop() {// put you…...
python创建args命令行分析
这段代码是一个使用 Python 的 argparse 模块创建命令行界面的示例。它定义了一系列的命令行参数和子命令,通常用于构建和管理软件项目或版本控制系统中的操作。以下是对代码的逐行分析: 1初始化 ArgumentParser parser argparse.ArgumentParser(forma…...

2. 手写数字预测 gui版
2. 手写数字预测 gui版 背景1.界面绘制2.处理图片3. 加载模型4. 预测5.结果6.一点小问题 背景 做了手写数字预测的模型,但是老是跑模型太无聊了,就配合pyqt做了一个可视化界面出来玩一下 源代码可以去这里https://github.com/Leezed525/pytorch_toy拿 …...
js数据类型有哪些?它们有什么区别?
js数据类型共有8种,分别是undefined,null,boolean,number,string,Object,symbol,bigint symbol和bigint是es6中提出来的数据类型 symbol创建后独一无二不可变的数据类型,它主要是为了解决出现全局变量冲突的问题 bigint 是一种数字类型的数据,它可以表示任意精度格式的整数,…...
大模型应用开发第五讲:成熟度模型:从ChatGPT(L2)到未来自主Agent(L4)
大模型应用开发第五讲:成熟度模型:从ChatGPT(L2)到未来自主Agent(L4) 资料取自《大模型应用开发:动手做AI Agent 》。 查看总目录:学习大纲 关于DeepSeek本地部署指南可以看下我之…...

特别篇-产品经理(三)
一、市场与竞品分析—竞品分析 1. 课后总结 案例框架:通过"小新吃蛋糕"案例展示行业分析方法,包含四个关键步骤: 明确目标行业调研确定竞品分析竞争策略输出结论 1)行业背景分析方法 PEST分析法:从四个…...
IP地址扫描 网络状态监测 企业网络管理 免安装,企业级 IP 监控防未授权接入
各位网络小卫士们!今天咱来聊聊一款超厉害的局域网IP地址扫描工具——IPScaner V1.22。这玩意儿就像网络世界的大侦探,能快速识别网络里设备的状态和资源分布。下面咱就好好唠唠它的那些事儿。 软件获取夸克网盘下载 先说说它的核心功能。第一个是IP…...

【unity游戏开发——编辑器扩展】AssetDatabase公共类在编辑器环境中管理和操作项目中的资源
注意:考虑到编辑器扩展的内容比较多,我将编辑器扩展的内容分开,并全部整合放在【unity游戏开发——编辑器扩展】专栏里,感兴趣的小伙伴可以前往逐一查看学习。 文章目录 前言一、AssetDatabase常用API1、创建资源1.1 API1.2 示例 …...

BLE协议全景图:从0开始理解低功耗蓝牙
BLE(Bluetooth Low Energy)作为一种针对低功耗场景优化的通信协议,已经广泛应用于智能穿戴、工业追踪、智能家居、医疗设备等领域。 本文是《BLE 协议实战详解》系列的第一篇,将从 BLE 的发展历史、协议栈结构、核心机制和应用领域出发,为后续工程实战打下全面认知基础。 …...

【机器学习基础】机器学习入门核心算法:GBDT(Gradient Boosting Decision Tree)
机器学习入门核心算法:GBDT(Gradient Boosting Decision Tree) 1. 算法逻辑2. 算法原理与数学推导2.1 目标函数2.2 负梯度计算2.3 决策树拟合2.4 叶子权重计算2.5 模型更新 3. 模型评估评估指标防止过拟合 4. 应用案例4.1 金融风控4.2 推荐系…...

基于开源AI大模型AI智能名片S2B2C商城小程序源码的销售环节数字化实现路径研究
摘要:在数字化浪潮下,企业销售环节的转型升级已成为提升竞争力的核心命题。本文基于清华大学全球产业研究院《中国企业数字化转型研究报告(2020)》提出的“提升销售率与利润率、打通客户数据、强化营销协同、构建全景用户画像、助…...

Spring Cache核心原理与快速入门指南
文章目录 前言一、Spring Cache核心原理1.1 架构设计思想1.2 运行时执行流程1.3 核心组件协作1.4 关键机制详解1.5 扩展点设计1.6 与Spring事务的协同 二、快速入门实战三、局限性3.1 多级缓存一致性缺陷3.2 分布式锁能力缺失3.3 事务集成陷阱 总结 前言 在当今高并发、低延迟…...

Redisson学习专栏(四):实战应用(分布式会话管理,延迟队列)
文章目录 前言一、为什么需要分布式会话管理?1.1 使用 Redisson 实现 Session 共享 二、订单超时未支付?用延迟队列精准处理2.1 RDelayedQueue 核心机制2.2 订单超时处理实战 总结 前言 在现代分布式系统中,会话管理和延迟任务处理是两个核心…...

java程序从服务器端到Lambda函数的迁移与优化
source:https://www.jfokus.se/jfokus24-preso/From-Serverful-to-Serverless-Java.pdf 从传统的服务器端Java应用,到如今的无服务器架构。这不仅仅是技术名词的改变,更是开发模式和运维理念的一次深刻变革。先快速回顾一下我们熟悉的“服务…...

使用yocto搭建qemuarm64环境
环境 yocto下载 # 源码下载 git clone git://git.yoctoproject.org/poky git reset --hard b223b6d533a6d617134c1c5bec8ed31657dd1268 构建 # 编译镜像 export MACHINE"qemuarm64" . oe-init-build-env bitbake core-image-full-cmdline 运行 # 跑虚拟机 export …...
Vue 3前沿生态整合:WebAssembly与TypeScript深度实践
一、Vue 3 WebAssembly:突破性能天花板 01、WebAssembly:浏览器中的原生性能 WebAssembly(Wasm)是一种可在现代浏览器中运行的二进制指令格式,其性能接近原生代码。结合Vue 3的响应式架构,我们可以在前端…...

Linux系统下安装配置 Nginx
Windows Nginx https://nginx.org/en/download.htmlLinux Nginx https://nginx.org/download/nginx-1.24.0.tar.gz解压 tar -zxvf tar -zxvf nginx-1.18.0.tar.gz #解压安装依赖(如未安装) yum groupinstall "Development Tools" -y yum…...
Kotlin 中集合遍历有哪几种方式?
1 for-in 循环(最常用) val list listOf("A", "B", "C") for (item in list) {print("$item ") }// A B C 2 forEach 高阶函数 val list listOf("A", "B", "C") list.forEac…...
图像卷积OpenCV C/C++ 核心操作
图像卷积:OpenCV C 核心操作 图像卷积是图像处理和计算机视觉领域最基本且最重要的操作之一。它通过一个称为卷积核(或滤波器)的小矩阵,在输入图像上滑动,并对核覆盖的图像区域执行元素对应相乘后求和的运算ÿ…...

LiveGBS作为下级平台GB28181国标级联2016|2022对接海康大华宇视华为政务公安内网等GB28181国标平台查看级联状态及会话
LiveGBS作为下级平台GB28181国标级联2016|2022对接海康大华宇视华为政务公安内网等GB28181国标平台查看级联状态及会话 1、GB/T28181级联概述2、搭建GB28181国标流媒体平台3、获取上级平台接入信息3.1、向下级提供信息3.2、上级国标平台添加下级域3.3、接入LiveGBS示例 4、配置…...
leetcode17.电话号码的字母组合:字符串映射与回溯的巧妙联动
一、题目深度解析与字符映射逻辑 题目描述 给定一个仅包含数字 2-9 的字符串 digits,返回所有它能表示的字母组合。数字与字母的映射关系如下(与电话按键相同): 2: "abc", 3: "def", 4: "ghi", …...

Gartner《2025 年软件工程规划指南》报告学习心得
一、引言 软件工程领域正面临着前所未有的变革与挑战。随着生成式人工智能(GenAI)等新兴技术的涌现、市场环境的剧烈动荡以及企业对软件工程效能的更高追求,软件工程师们必须不断适应和拥抱变化,以提升自身竞争力并推动业务发展。Gartner 公司发布的《2025 年软件工程规划…...