#javascript #reactjs #svg #frontend
#javascript #reactjs #svg #интерфейс
Вопрос:
У меня есть модуль, который отображает svg. Перед этим модуль должен проверить авторизацию и, если все в порядке, извлечь файл из api через вызов с помощью токена.
У меня есть следующий код
function App() {
const [tableColors, setTableColors] = useState(["gray"]);
const [svg, setSvg] = useState(false);
const [isLoaded, setIsLoaded] = useState(false);
const [isErrored, setIsErrored] = useState(false);
new AuthService().getUser().then(user =>{ if(!user) {
Login()
}
else{
useEffect( async () => {
LoadSvg()
.then(res => res.text())
.then(setSvg)
.catch(setIsErrored)
.then(() => setIsLoaded(true))
}, [])
}})
return (
<div className="App">
<header className="App-header">
<SvgLoader svgXML={svg}>
</SvgLoader>
</header>
</div>
);
function Login(){
var a = new AuthService();
a.login();
}
async function LoadSvg(){
return await new ApiService().callApi("https://localhost:44338/api/v1/desk-booking/Plan/getroomplanbyid?roomId=1")
}
}
И проблема, с которой я сталкиваюсь здесь, заключается в том, что «useEffect»useEffect» не может быть вызван внутри обратного вызова», но без использования «useEffect» он бесконечно извлекает svg.
Как я могу решить проблему?
Комментарии:
1.
useEffect
не следует использовать условно. Глядя на код, я бы сказал, что вам также нужно поместить свою аутентификацию в useEffect.2. Это первое правило хуков: вызывать хуки только на верхнем уровне. reactjs.org/docs/hooks-rules.html
Ответ №1:
Вы делаете это неправильно, если вы делаете это «реагирующим» способом, тогда решение будет выглядеть так
....
function App() {
const [tableColors, setTableColors] = useState(['gray']);
const [svg, setSvg] = useState(false);
const [isLoaded, setIsLoaded] = useState(false);
const [isErrored, setIsErrored] = useState(false);
// state to check if user is loaded, used for svg call
const [userLoaded, setUserLoaded] = useState(false);
// useEffect does not prefer async function
useEffect(() => {
if (!userLoaded) {
new AuthService().getUser().then(user => {
if (!user) {
Login();
// indicate user was loaded
// I would move the login function body here instead since, login is async, so this might not work as intended but you get the idea
setUserLoaded(true);
}
});
}
}, [])
useEffect(() => {
// if userLoaded is true then go ahead with svg loading
if (userLoaded) {
LoadSvg()
.then(res => res.text())
.then(setSvg)
.catch(setIsErrored)
.then(() => setIsLoaded(true));
}
// Add svg useEffect dependency on userLoaded
}, [userLoaded]);
......
Обратите внимание, это решение предназначено для того, чтобы дать вам представление о том, как это сделать, оно может не сработать, если вы скопируете и вставите код.