Noob UseEffect problems



我试图显示一个基于promise响应(true o false(的页面(让我们称之为/abc(,所以我发现使用usestate和useeffect是可能的,看起来几乎可以工作/abc显示正确,但我有两个问题:

  1. 当我刷新页面时,如果刷新后值为true,则返回false,如果为false,则刷新后返回false它应该是,但当我从另一个页面进入/abc时,它按预期工作
  2. 当我从另一页切换到/abc时,一切都很好,但当我从/abc切换到另一页时,我得到了react-dom.development.js:188 Uncaught TypeError: func.apply is not a function,我发现这与以下事实有关useEffect不能返回不是函数的东西,但我我真的不知道如何让它发挥作用

这是代码:

const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
async function doSomething() {
let result = await writeContracts && writeContracts.Whitelist.isWhitelisted(address);
return result  // result is the promise 
}
async function test(){
var isWhitelisted = await doSomething()
if (isWhitelisted == true){
return true
}else{       
return false}
}

useEffect(async () => {
try {
setLoading(true);
const dat = await test();
setData(dat);
setLoading(false);
}
}, []);

然后

if(loading) {return (
<span>Loading</span> )};
if (data == false ){ return ( 
<div>False</div> )};
else { return (
<div>True</div> )};

我知道关于如何获得promise值的逻辑可能是错误的(因为这里的一切可能都是错误的(,但我花了几个小时试图理解如何单独获得promise响应,在另一个函数中调用该函数是唯一返回true或false的事情,我花了更多的时间试图弄清楚这个钩子是如何工作的。

据我所知,异步useEffect是一个反模式。您应该重构代码以避免这种情况。类似于:

useEffect(() => {
async function fetchMyAPI() {
const dat = await test();
setData(dat);
}
try {
setLoading(true);
fetchMyAPI();
setLoading(false);
}
}, []);

请仔细阅读,你会很容易得到的我为您创建了一个示例应用程序https://codesandbox.io/s/thirsty-sea-k58x3?file=/src/App.js:0-821

import { useEffect, useState } from "react";
import "./styles.css";
import axios from "axios";
export default function App() {
//state for storing the data
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
//calling api for data
const getUserData = async () => {
setLoading(true);
let response = await axios.get(
"https://jsonplaceholder.typicode.com/posts"
);
setLoading(false);
setData(response.data);
};
useEffect(() => {
getUserData();
}, []);
//function for maping API Data
const displayUserData = () => {
return data.map((item) => {
return (
<ul>
<li>{item.title}</li>
</ul>
);
});
};
return (
<div className="App">{loading ? <p>Loading</p> : displayUserData()}</div>
);
}

将useEffect作为async函数的这种方式是反模式的,因为cleanup函数不会执行。一种方法是在useEffect()钩子内有一个立即调用函数表达式(IIFE(。

useEffect(() => {
(async () => {
try {
setLoading(true);
const dat = await test();
setData(dat);
setLoading(false);
}
})();
}, []);

第二种方法是在useEffect()钩子内定义异步函数。

useEffect(() => {
const getResult = async () => {
setLoading(true);
const dat = await test();
setData(dat);
setLoading(false);
};
getResult();
}, []);

最新更新