У меня есть фрагмент кода, который получает метаданные списка файлов из хранилища Firebase с помощью хука useEffect. Однако я изо всех сил пытаюсь обновить свое состояние в этом useEffect. Я использовал шаблон async/await, чтобы смягчить асинхронный характер setState, но без особого успеха.
Мой фрагмент в псевдокоде:
const [someData,setSomeData]=useState([])
const dataArray=[]
useFocusEffect(
useCallback(()=>{
async function getData(){
const result=await listAll(storageRef);
await result.items.map(async (itemRef)=>{
const Metadata=await getMetadata(itemRef);
await dataArray.push({'name':Metadata.name})
await console.info(dataArray) //shows the array being populated on each iteration
})
await setSomeData(dataArray);
await console.info(someData) // I'm expecting it to print an updated state, prints an empty array instead
}
getData()
},[])
)
Я также не могу получить доступ к состоянию в возвращаемой части моего кода:
return(
{someData.map(({item})=>{
return(
<View><Text>{item.name}</Text><View>)})
ничего не выводит, насколько я могу судить.
Чего мне не хватает в моем подходе?
заранее спасибо
dataArray
повторно инициализируется в []
при каждом рендеринге, а затем вы устанавливаете someData
в dataArray
, эффективно устанавливая someData
в пустой массив. Я думаю, что если вы завернете свою асинхронную карту в Promise.all, тогда вы можете иметь dataArray, привязанный к вашей функции getData
:
const fetchData = useCallback(() => {
async function getData() {
const result = await listAll(storageRef);
const dataArray = await Promise.all(
result.items.map(async (itemRef) => {
const Metadata = await getMetadata(itemRef);
console.info(Metadata);
return { name: Metadata.name };
})
);
console.info("dataArray:\n", dataArray);
setSomeData(dataArray);
// even if you await setSomeData, someData wont be the the updated value.
/* If you want to see someData changes do
useEffect(()=>{
console.info(someData)
},[someData])
*/
}
getData();
}, []);
useFocusEffect(fetchData);