我有一個具有以下功能的 api.js 檔案:
export const login = (loginUserName, loginPassword, setUser) => {
axios({
method: 'post',
data: {
username: loginUserName,
password: loginPassword
},
withCredentials: true,
url: '...........'
}).then(async (res) => {
if (res.data.loggedIn === true) setUser(loginUserName);
});
};
我的 useState 鉤子如下所示:
const [ user, setUser ] = useState({});
我想知道,而不是像我一樣從我的 Login 組件發送 setUser 函式:
login(userName,password,setUser);
這是在另一個檔案中,我如何從函式外部執行此操作,如下所示:
setUser(login(userName,password));
因此,如果該函式確實檢索到了我想要的資訊,它將回傳它(在這種情況下是用戶名),如果沒有,它會將用戶設定為未定義或其他內容。
我嘗試使用
export const login = (loginUserName, loginPassword) => {
axios({
method: 'post',
data: {
username: loginUserName,
password: loginPassword
},
withCredentials: true,
url: '............'
}).then(async (res) => {
if (res.data.loggedIn === true) return loginUserName;
});
};
但是我在異步功能方面遇到了一些困難。似乎出于某種原因它不會回傳該資訊。如果我不得不猜測它只為 axios 函式或其他東西回傳它......我如何獲得我正在尋找的效果以及最佳實踐是什么?發送“setUser”函??數是否被認為是一種好習慣,還是試圖擺脫它更好?
uj5u.com熱心網友回復:
所以這里發生了一些不同的(但相關的、有效的)事情。首先,這
setUser(login(userName,password));
不會作業。您不能與服務器同步交談。您當前將 setteruseState作為回呼傳遞的方法很好。真的。這樣做絕對沒有錯。
但我也不會稱之為最佳實踐。“最佳實踐”有點主觀,但您可以通過以下另一種方式做到這一點:
// useUser.js
import React, { createContext, useContext, useState, useEffect } from 'react'
// could be in another file and imported, whatever.
const login = async (userName, userPass) => {
const data = await axios(...);
return data.loggedIn ? data : null; // could also throw
};
const UserContext = createContext([]); // user data and setter, eventually
const UserProvider = ({ children }) => {
const userState = useState({});
return (<UserContext.Provider value={userState}>
{children}
</UserContext.Provider>);
};
export const useUser = () => {
const [userData] = useContext(UserContext);
return userData
}
export useLogin = (userName = '', userPass = '') => {
const [_, setUserData] = useContext(UserContext);
useEffect(() => {
if (userName && userPass) {
login(userName, userPass)
.then(data => {
if (data) setUserData(data);
}); // add .catch to handle errors
}
}, [userName, userPass, setUserData])
}
然后,在你的 App.js
import React from 'react';
import { UserProvider } from 'path/to/file.js';
function App({ children }) {
// code
return <UserProvider>{children}</UserProvider>;
}
在依賴用戶資料的任何組件中,您現在可以
import React from 'react';
import { useUser } from 'path/to/file.js';
export default (props) => {
const userData = useUser();
return <div>{userData.name || 'loading'}</div>;
}
在您的登錄表單中,您可以執行
import React, { useState } from 'react';
import { useLogin } from 'path/to/file.js';
export default (props) => {
const [userName, setUserName] = useState('');
const [userPass, setUserPass] = useState('');
useLogin(userName, userPass);
return <form>...</form>;
};
通過創建背景關系和自定義鉤子,現在樹中的任何組件都可以通過呼叫鉤子來訪問用戶資料。您不想對此感到瘋狂,但是用戶資料通常用于各個級別,并且將其作為道具傳遞給所有中間組件是很乏味的。這種模式可以被抽象化,雖然它看起來像很多代碼,但與所有 redux 相比,它在頁面權重上更容易。
因為我們不匯出背景關系物件本身或用戶資料設定器,所以您不必擔心消費者不小心修改了他們不應該修改的東西,這里我們只公開具有設定器(useLogin)功能的 API 的鉤子和一個吸氣劑(useUser)。
您還可以將背景關系提供程式進一步向下移動(或者進一步向上移動,您可以將您的 App 組件包裝在其中),但這取決于您需要在何處使用它。
uj5u.com熱心網友回復:
您的setUser函式僅在宣告它的組件內有效,所以是的,只需回傳獲取結果并處理設定該特定組件內的狀態。
你沒有得到任何回傳的原因可能是請求沒有成功(檢查你瀏覽器的網路選項卡和相關回應)或者你沒有await得到結果(獲取總是一個異步操作,所以你必須期望有延遲的回應)。
你可以這樣做:
useEffect(() => {
(async () => {
const username = await login(userName,password,setUser);
setUser(username);
})();
}, []);
uj5u.com熱心網友回復:
如果我需要在我的應用程式流程中使用的狀態物件,例如我計劃傳遞給大多數子組件的用戶物件。然后我寧愿使用 Redux 庫來創建一個我可以在所有組件中訪問的商店。
需要做很多作業才能讓它作業,所以我在閱讀檔案時會很小心,但使用給定的工具進行作業是值得的。
然后,您可以訪問/操作商店狀態,如下所示:
import React, { useState } from 'react';
import { useAppSelector, useAppDispatch } from 'app/hooks';
import { decrement, increment } from './counterSlice';
function login(loginUserName, loginPassword) {
const dispatch = useAppDispatch();
axios({
method: 'post',
data: {
username: loginUserName,
password: loginPassword
},
withCredentials: true,
url: '............'
}).then(async (res) => {
if (res.data.loggedIn === true) {
dispatch(setUser(loginUserName));
}
};
}
export function Login() {
login("User Name", "********");
const user = useAppSelector((state) => state.user.value);
console.log(user);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/401244.html
標籤:javascript 反应 阿贾克斯 异步 公理
上一篇:在發送回應NodeExpress之前等待python腳本運行
下一篇:為什么我的組件沒有接收異步資料?
