Node.js 在react和nodejs中实时更新
我试图实现当用户上传他们的个人资料图片到网站上,它会自动将旧的个人资料图片更改为新的个人资料图片,而不是用户必须注销并重新登录,使其工作 以下是我的前端代码库:Node.js 在react和nodejs中实时更新,node.js,reactjs,next.js,Node.js,Reactjs,Next.js,我试图实现当用户上传他们的个人资料图片到网站上,它会自动将旧的个人资料图片更改为新的个人资料图片,而不是用户必须注销并重新登录,使其工作 以下是我的前端代码库: const UserCard = ({ picture, name, userEmail, isVerified, id, setPicture, setUser}) => { const [imageSelected, setImageSelected] = useState("");
const UserCard = ({ picture, name, userEmail, isVerified, id, setPicture, setUser}) => {
const [imageSelected, setImageSelected] = useState("");
useEffect(() => {
if (imageSelected !== '') {
uploadImage();
}
}, [imageSelected]);
const uploadImage = () => {
const formData = new FormData();
formData.append("file", imageSelected);
formData.append("id", id);
axios
.post("/api/v1/users/upload/image", formData, {
headers: { "Content-Type": "multipart/form-data" },
})
.then((response) => {
setPicture(response.data.data.imageUrl);
setUser(prev => ({ ...prev, picture: response.data.data.imageUrl }));
});
};
// End of Method
const inputFile = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted file input element
inputFile.current.click();
};
return (
<div className="avatar--icon_profile">
<Card className="profile--card_container">
<CardContent>
{picture ? (
<div>
<input
className="my_file"
type="file"
ref={inputFile}
onChange={(e) => setImageSelected(e.target.files[0])}
/>
<div className="profile-image">
<Avatar
src={picture}
alt="Avatar"
className="avatar--profile_image"
onClick={onButtonClick}
/>
</div>
</div>
</div>
我怎样才能做到呢
添加了GlobalState.js:
const GlobalState = (props) => {
// User State -----------------------------------------------------------------------------
const [currentUser, setUser] = useState(props.serverUserData);
// This method is passed through context to update currentUser
const updateUser = (userData) => {
setUser(userData);
};
// Modal State -----------------------------------------------------------------------------
const [isModalOpen, setModalOpenState] = useState(false);
const [modalToDisplay, setModalToDisplay] = useState("signup");
// This function will be provided to any function that needs to toggle the modal.
const toggleModal = () => {
// Take the previous state and flip it.
setModalOpenState((prevState) => !prevState);
};
// This method is passed through context to update the next modal to open.
const setModal = (name) => {
// Take the passed in modal name and set state.
setModalToDisplay(name);
};
// Loading State ---------------------------------------------------------------------------
// NOT REACT STATE
const [loading, setLoadingState] = useState(false);
// This state will be used as messages in effects to refetch data.
const [reloadThisData, setWhatToReload] = useState("");
// User profile id for query ----------------------------------------------------------------
const [userProfileId, setUserProfileId] = useState("");
// Flag to determine if the header should change css style. ----------------------------------------------------------------
const [adjustBrightness, setAdjustBrightness] = useState(false);
// This is the object passed to GlobalContext.Provider
const providerValues = {
isModalOpen,
toggleModal,
modalToDisplay,
setModal,
currentUser,
updateUser,
loading,
setLoadingState,
reloadThisData,
setWhatToReload,
userProfileId,
setUserProfileId,
adjustBrightness,
setAdjustBrightness,
};
return (
<GlobalContext.Provider value={providerValues}>
{props.children}
</GlobalContext.Provider>
);
};
export default GlobalState;
编辑后更新我的代码:
const UserProfile = () => {
const appState = useContext(GlobalContext);
const { currentUser, setUser } = appState;
const { email, name, id } = currentUser;
const [isVerified, setIsVerified] = useState(false);
const [picture, setPicture] = useState(currentUser.picture);
const checkVerificationData = () => {
axios.get("/api/v1/profiles/profile").then((res) => {
const { data } = res;
if (data.verifiedDT) {
setIsVerified(data.verifiedDT);
}
});
};
useEffect(() => {
checkVerificationData();
}, [isVerified]);
const classes = useStyles();
return (
<div className={classes.root}>
<Grid item xs={12}
container
direction="row"
justify="center"
alignItems="center"
spacing={4}>
<Grid item>
<Grid item>
<UserCard
picture={picture}
setPicture={setPicture}
userEmail={email}
name={name}
isVerified={isVerified}
id={id}
setUser={setUser}
/>
<br />
</Grid>
<div>
<Grid item>
<div className="profile--layout_userInfo">
<Grid item>
<UserInfo />
</Grid>
</div>
</Grid>
</div>
</Grid>
<div>
<Grid item>
<div className="profile--layout_ratings_reviews_block">
<UserRatingsDetailed userEmail={email} />
</div>
</Grid>
</div>
</Grid>
</div>
);
};
export async function getServerSideProps(context) {
let serverUserData = {};
if (
context.req.session.passport !== undefined &&
context.req.session.passport.user !== undefined
) {
const userPassportInfo = context.req.session.passport.user;
const { id, name, email, publicId, picture } = userPassportInfo;
const isSessionValid = context.req.isAuthenticated();
serverUserData = {
id,
name,
email,
publicId,
picture,
isSessionValid,
};
}
return { props: { serverUserData } };
}
UserProfile.propTypes = {
serverUserData: PropTypes.object,
};
export default UserProfile;
constuserprofile=()=>{
const appState=useContext(GlobalContext);
const{currentUser,setUser}=appState;
const{email,name,id}=currentUser;
const[isVerified,setIsVerified]=使用状态(false);
const[picture,setPicture]=useState(currentUser.picture);
常量checkVerificationData=()=>{
get(“/api/v1/profiles/profile”)。然后((res)=>{
常数{data}=res;
if(数据验证数据){
setIsVerified(data.verifiedDT);
}
});
};
useffect(()=>{
checkVerificationData();
},[isVerified]);
const classes=useStyles();
返回(
);
};
导出异步函数getServerSideProps(上下文){
让serverUserData={};
如果(
context.req.session.passport!==未定义&&
context.req.session.passport.user!==未定义
) {
const userPassportInfo=context.req.session.passport.user;
const{id,name,email,publicId,picture}=userPassportInfo;
const isSessionValid=context.req.isAuthenticated();
serverUserData={
身份证件
名称
电子邮件,
publicId,
图片,
是有效的,
};
}
返回{props:{serverUserData}};
}
UserProfile.propTypes={
serverUserData:PropTypes.object,
};
导出默认用户配置文件;
我从回答表单中的评论中得到的建议是,在react应用程序的全局上下文中创建一个类似于其他经理的经理
const GlobalState = (props) => {
// Profile Image -----------------------------------------------------------------------
const [currentProfileImage, setProfileImage] = useState(/*props.serverUserData.profileImage??*/);
...
};
export default GlobalState;
不要忘记更新您的providerValues
以包含这些新值
然后,在使用概要文件映像URI的任何位置,都可以使用上下文提供程序中的currentProfileImage
变量
最后,当您将映像上载到服务器并在响应中接收新URI时,请使用来自全局状态的setProfileImage
函数更新全局状态下的概要文件映像
const uploadImage = () => {
const formData = new FormData();
formData.append("file", imageSelected);
formData.append("id", id);
axios.post("/api/v1/users/upload/image", formData, {
headers: {"Content-Type": "multipart/form-data"},
}).then((response) => {
GlobalState.setProfileImage(response.data.data.imageUrl);
});
};
*我对您的程序没有完整的了解,因此这是我对实现您期望行为的合理方式的最佳猜测
您需要更新
useState
指令的初始状态,以反映profileImage URI在props
结构中的实际位置,您需要更新GlobalState
占位符,以反映您实际访问所提供上下文的方式。您提到注销和登录是显示新配置文件图片的方式,而不是简单的页面刷新。这是因为您在登录过程中对配置文件图片信息进行了初始拉取吗?@HenryEcker我不明白您所说的初始拉取是什么意思?我想我的问题是:您通常如何检索用户的配置文件图片?在你的uploadImage
函数的末尾,这样做不是一个选项吗?我通过上下文检索用户的信息。我在帖子中添加了我的上下文,然后我的建议是在全局上下文管理中添加类似于getUserProfileImage
的内容,并在上传新图像后调用它。或者,由于您似乎正在返回照片的新url,请添加一个updateUserProfileLink
并将新url传递给该url。我刚刚在帖子中添加了console.log currentUser对象。这就是我需要放在useState中的对象吗?props.serverUserData.picture
或currentUser.picture
您只是想更新图片URI。有了关于当前用户结构的新信息,您可能只需使用现有的用户挂钩,并使用currentUser.picture
和setUser(prev=>({…prev,picture:response.data.data.imageUrl}))
。我也不知道在UserProfile
和UserCard
级别创建新挂钩是否有效。我认为您需要直接从上下文访问它们,比如appState.setUser({…}
或appState.currentUser.picture
当前,您似乎只是保留了一个本地副本,而不是直接使用上下文值。
const GlobalState = (props) => {
// Profile Image -----------------------------------------------------------------------
const [currentProfileImage, setProfileImage] = useState(/*props.serverUserData.profileImage??*/);
...
};
export default GlobalState;
const uploadImage = () => {
const formData = new FormData();
formData.append("file", imageSelected);
formData.append("id", id);
axios.post("/api/v1/users/upload/image", formData, {
headers: {"Content-Type": "multipart/form-data"},
}).then((response) => {
GlobalState.setProfileImage(response.data.data.imageUrl);
});
};