[英]refresh user data when changes are made to mongodb
我是新來的反應和 MongoDB,我有這個網站,用戶可以登錄並查看他的詳細信息,如姓名……,來自數據庫。 我試圖找到一種方法來更新直接從數據庫進行更改時顯示給客戶端的內容,或者單擊按鈕刷新用戶數據時,它會顯示來自數據庫的新更新數據。 我正在使用 useReducer 對用戶進行身份驗證並從客戶端對他進行更新,但我找不到更新顯示給客戶端的數據的方法。 如果直接從數據庫進行更改,則用戶必須注銷並重新登錄才能查看它們的更新版本。 再說一次,我對 useReducer 還是很陌生,而且我只能勉強讓它從我能找到的東西中工作,但我在任何地方都找不到這個特殊的問題。 如果有人可以提供幫助,我將不勝感激。 如果您需要更多上下文或任何其他文件,請告訴我。
我的 AuthContext 文件與 useReducer
import React from "react";
import { createContext, useEffect, useReducer } from "react";
const INITIAL_STATE = {
user: JSON.parse(localStorage.getItem("user")) || null,
loading: false,
error: null,
};
export const AuthContext = createContext(INITIAL_STATE);
const AuthReducer = (state, action) => {
switch (action.type) {
case "LOGIN_START":
return {
user: null,
loading: true,
error: null,
};
case "LOGIN_SUCCESS":
return {
user: action.payload,
loading: false,
error: null,
};
case "LOGIN_FAILURE":
return {
user: null,
loading: false,
error: action.payload,
};
case "LOGOUT":
return {
user: null,
loading: false,
error: null,
};
case "UPDATE_USER_DATE":
const updatedUser = { ...state.user };
updatedUser.activeUntil = action.payload;
return {
...state,
user: updatedUser,
};
case "UPDATE_USER":
const updateUser = { ...state.user };
return {
...state,
user: updateUser,
};
default:
return state;
}
};
export const AuthContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(AuthReducer, INITIAL_STATE);
useEffect(() => {
localStorage.setItem("user", JSON.stringify(state.user));
}, [state.user]);
return (
<AuthContext.Provider
value={{
user: state.user,
loading: state.loading,
error: state.error,
dispatch,
}}
>
{children}
</AuthContext.Provider>
);
};
我正在嘗試進行更新的地方
import React, { useContext } from "react";
import { useState } from "react";
import useFetch from "../../hooks/useFetch";
import Footer from "../../components/OutFooter";
import Navbar from "../../components/OutNavbar";
import Sidebar from "../../components/OutSidebar";
import {
ContractContainer,
HeadingContainer,
TypeH1,
ActiveUntil,
MonthlyWrapper,
MonthlyContainer,
MonthNumber,
Price,
Navbarback,
} from "./userinfoElements";
import { AuthContext } from "../../context/AuthContext";
import { Navigate } from "react-router-dom";
import moment from "moment";
import axios from "axios";
const Userinfo = () => {
// for nav bars
const [isOpen, setIsOpen] = useState(false);
// set state to true if false
const toggle = () => {
setIsOpen(!isOpen);
};
const { user, dispatch } = useContext(AuthContext);
if (!user) {
return <Navigate to="/" />;
}
const { data } = useFetch(`/contracts/${user.contractType}`);
let dateFormat = moment(user.activeUntil).format("DD/MMMM/yyyy");
const update1Month = async () => {
try {
let newDate = moment(user.activeUntil).add(30, "days");
dateFormat = newDate.format("DD/MMMM/yyyy");
await axios.put(`/activedate/${user.namekey}`, {
activeUntil: newDate,
});
dispatch({ type: "UPDATE_USER_DATE", payload: newDate });
} catch (err) {
console.log(err);
}
};
const update3Month = async () => {
try {
let newDate = moment(user.activeUntil).add(90, "days");
dateFormat = newDate.format("DD/MMMM/yyyy");
await axios.put(`/activedate/${user.namekey}`, {
activeUntil: newDate,
});
dispatch({ type: "UPDATE_USER_DATE", payload: newDate });
} catch (err) {
console.log(err);
}
};
const update6Month = async () => {
try {
let newDate = moment(user.activeUntil).add(180, "days");
dateFormat = newDate.format("DD/MMMM/yyyy");
await axios.put(`/activedate/${user.namekey}`, {
activeUntil: newDate,
});
dispatch({ type: "UPDATE_USER_DATE", payload: newDate });
} catch (err) {
console.log(err);
}
};
const update12Month = async () => {
try {
let newDate = moment(user.activeUntil).add(365, "days");
dateFormat = newDate.format("DD/MMMM/yyyy");
await axios.put(`/activedate/${user.namekey}`, {
activeUntil: newDate,
});
dispatch({ type: "UPDATE_USER_DATE", payload: newDate });
} catch (err) {
console.log(err);
}
};
const refreshUser = async () => {
try {
dispatch({ type: "UPDATE_USER" });
} catch (err) {
console.log(err);
}
};
return (
<>
<Sidebar isOpen={isOpen} toggle={toggle} />
{/* navbar for smaller screens*/}
<Navbar toggle={toggle} />
<Navbarback /> {/* filling for transparent bacground navbar*/}
<>
<ContractContainer>
<button onClick={refreshUser}>toooo</button>
<TypeH1>
Hello {user.fName} {user.lName}!
</TypeH1>
<HeadingContainer>
<TypeH1>{data.contractType}</TypeH1>
<ActiveUntil>Subscription active until {dateFormat}</ActiveUntil>
</HeadingContainer>
<MonthlyWrapper>
<MonthlyContainer>
<MonthNumber>1 Month</MonthNumber>
<Price onClick={update1Month}>{data.month1Price}$</Price>
</MonthlyContainer>
<MonthlyContainer>
<MonthNumber>3 Month</MonthNumber>
<Price onClick={update3Month}>{data.month3Price}$</Price>
</MonthlyContainer>
<MonthlyContainer>
<MonthNumber>6Month</MonthNumber>
<Price onClick={update6Month}>{data.month6Price}$</Price>
</MonthlyContainer>
<MonthlyContainer>
<MonthNumber>12Month</MonthNumber>
<Price onClick={update12Month}>{data.month12Price}$</Price>
</MonthlyContainer>
</MonthlyWrapper>
</ContractContainer>
</>
<Footer />
</>
);
};
export default Userinfo;
特別是->
const refreshUser = async () => {
try {
dispatch({ type: "UPDATE_USER" });
} catch (err) {
console.log(err);
}
};
我懷疑您可以通過直接從數據庫中更改文檔來導致重新渲染。 不過如果想要刷新按鈕,可以先新建一個state
const [refresh, setRefresh] = React.useState(false)
然后將此 onClick 處理程序傳遞給刷新按鈕,該按鈕與您的用戶詳細信息位於同一組件中
<button onClick = {() => setRefresh(prev => !prev)}>Refresh</button>
在這里和那里涉足之后,我意外地得到了我需要的東西。 我發現使用 useEffect 我可以在頁面加載開始時加載 function 。 不小心這樣做也導致將我的本地存儲用戶更新為我數據庫中的用戶。 我在上下文文件中更改了一些內容,並在 api 一側添加了一個新的 controller,該側發布了已存儲的用戶。 如果有人需要進一步的解釋或示例,請隨時詢問!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.