import React, { useState, useEffect } from 'react';
import useGunContext from './useGunContext';
const APP_PUBLIC_KEY = process.env.APP_PUBLIC_KEY;
const UserList = () => {
const { getGun } = useGunContext();
const [users, setUsers] = useState({});
useEffect(() => {
getGun()
.get(`~${APP_PUBLIC_KEY}`)
.get('profiles')// 进一步访问 profiles 节点,通常用于存储所有用户的个人资料数据
.map() // map() 方法会遍历 profiles 节点下的所有子节点,并对每个子节点执行接下来的 on() 回调函数, map() 方法类似于 JavaScript 的 forEach(),但它是实时的。当 profiles 节点下的任何数据发生变化时,map() 会自动触发更新。
.on((profile, pub) => {
setUsers((users) => ({
...users,
[pub]: profile,
}));
});
}, []);
return (
<div>
<ul>
{Object.entries(users).map(([pub, user]) => (
<li key={pub}>
{user.displayName} ({user.username})
</li>
))}
{console.log(`~${APP_PUBLIC_KEY}`)}
{/* ~B14-m6S3i1cgm9bJCsED0FsGbHiDlXJAiKK2OnrPSj0.axmMDTmbdAfU3SjJhgqOn6mH6jDUoazcQ_vHljstyuE */}
</ul>
</div>
);
};
export default UserList;
UserInfo.js
- 修改显示名称和密码
- 处理方式类似,只是多了认证选项:
{ opt: { cert: getCertificate() } } - cert 是 Gun.js 认证机制的一部分:getCertificate() 是useGunContext处理的函数,用于生成当前用户的写入权限证书。该证书确保只有拥有正确权限的用户(通常是数据所有者或管理员)才能修改某些节点。这是 Gun.js 用于访问控制的机制。
import React, { useState } from 'react';
import useGunContext from './useGunContext';
const APP_PUBLIC_KEY = process.env.APP_PUBLIC_KEY;
export default function UserInfo() {
const { getGun, getUser, getCertificate } = useGunContext();
const [displayName, setDisplayName] = useState('');
const [oldPassword, setOldPassword] = useState('');
const [newPassword, setNewPassword] = useState('');
const [authError, setAuthError] = useState();
const [authSuccess, setAuthSuccess] = useState();
const [profileEditError, setProfileEditError] = useState();
const [profileEditSuccess, setProfileEditSuccess] = useState();
const handleSubmitProfile = (e) => {
e.preventDefault();
setProfileEditError();
setProfileEditSuccess();
getGun()
.get(`~${APP_PUBLIC_KEY}`)
.get('profiles')
.get(getUser().is.pub)
.put(
{ displayName: displayName },
({ err }) => {
if (err) {
setProfileEditError(err);
} else {
setProfileEditSuccess(
`Successfully changed display name to ${displayName}`
);
}
},
{
opt: { cert: getCertificate() },
}
);
};
const handleSubmitPassword = (e) => {
e.preventDefault();
setAuthError();
setAuthSuccess();
const user = getUser();
// re-auth user
user.get('alias').then((username) => {
user.auth(username, oldPassword, ({ err, sea }) => {
if (err) {
setAuthError('Wrong password');
} else {
user.auth(
sea,
({ err }) => {
if (err) {
setAuthError(err);
} else {
setAuthSuccess('Password successfully changed');
}
},
{
change: newPassword,
}
);
}
});
});
};
return (
<div>
<h3>edit profile</h3>
<form onSubmit={handleSubmitProfile}>
<div>
<label>
display name
<input
name="display_name"
value={displayName}
onChange={(e) => setDisplayName(e.target.value)}
/>
</label>
</div>
{profileEditError && (
<div style={{ color: 'red' }}>{profileEditError}</div>
)}
{profileEditSuccess && (
<div style={{ color: 'green' }}>{profileEditSuccess}</div>
)}
<div>
<button type="submit">save changes</button>
</div>
</form>
<h3>change password</h3>
<form onSubmit={handleSubmitPassword}>
<div>
<label>
old password
<input
name="password"
type="password"
value={oldPassword}
onChange={(e) => setOldPassword(e.target.value)}
/>
</label>
</div>
<div>
<label>
new password
<input
name="new_password"
type="password"
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
/>
</label>
</div>
{authError && <div style={{ color: 'red' }}>{authError}</div>}
{authSuccess && <div style={{ color: 'green' }}>{authSuccess}</div>}
<div>
<button type="submit">save changes</button>
</div>
</form>
</div>
);
}