使用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库然后加入代码

javascript 复制代码
import { createClient } from '@supabase/supabase-js'

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY

export const supabase = createClient(supabaseUrl, supabaseAnonKey)

我们就相当于项目和数据库完全的连接了并且可以直接使用supabase-js里面的方法api以及后端逻辑。

那么剩下的步骤就是开发也就是写代码了。

这里我就都不写出来了我只写登入以及信息页面的代码。

javascript 复制代码
		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>
		<input
		className="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>
		)
		}
		

这是登录页面,下面是个人信息页面

TypeScript 复制代码
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页面

javascript 复制代码
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是否返回也就是是否登录来判断渲染登录页还是账户页面

然后再账户页面,核心就是

javascript 复制代码
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大概这就是核心思路,扩展的上传头像框可以去对应的文档练习,我觉得关键的思路这些已经齐全了,大家可以评论指点我一下,谢谢大家。

相关推荐
SPC的存折3 分钟前
6、MySQL设置TLS加密访问
linux·运维·服务器·数据库·mysql
老苏畅谈运维3 分钟前
DBA分析 ORA 报错的利器,errorstack让 Oracle 错误现原形
数据库·oracle·dba
紫青宝剑30 分钟前
向量数据库 Milvus
数据库·milvus
雪碧聊技术31 分钟前
数据库系统基础知识
数据库
Elastic 中国社区官方博客31 分钟前
如何使用 LogsDB 降低 Elasticsearch 日志存储成本
大数据·运维·数据库·elasticsearch·搜索引擎·全文检索·可用性测试
Dreamboat-L32 分钟前
HBase远程访问配置(详细教程)
大数据·数据库·hbase
刘~浪地球34 分钟前
数据库与缓存--Redis 集群架构与优化
数据库·redis·缓存
羊小蜜.35 分钟前
Mysql 11: 存储过程全解——从创建到使用
android·数据库·mysql·存储过程
A__tao36 分钟前
一键实现 SQL 转 Elasticsearch Mapping(支持字段注释 + meta 描述)
数据库·sql·elasticsearch
努力努力再努力wz44 分钟前
【C++高阶系列】外存查找的极致艺术:数据库偏爱的B+树底层架构剖析与C++完整实现!(附B+树实现的源码)
linux·运维·服务器·数据结构·数据库·c++·b树