如何从React Native中API调用副作用更新状态?[duplicate]

r7knjye2  于 2023-01-09  发布在  React
关注(0)|答案(2)|浏览(125)
    • 此问题在此处已有答案**:

The useState set method is not reflecting a change immediately(16个答案)
(13个答案)
6小时前关门了。
我有一段代码,它使用useEffect钩子从Firebase存储中获取文件列表的元数据。然而,我很难在这个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.log(dataArray) //shows the array being populated on each iteration
            })
            await setSomeData(dataArray);
            await console.log(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>)})

据我所知没有任何输出。
我的方法遗漏了什么?
先谢了

0pizxfdo

0pizxfdo1#

  • SometData()不返回承诺,因此无法等待。
  • dataArray需要在getData()内确定作用域
  • getData在someData周围闭合,因此它永远不会获得更新的值,因为该函数调用引用的是以前的值
  • 使用react native compatible async data library可能更容易
cvxl0en2

cvxl0en22#

dataArray在每次渲染时都被重新初始化为[],然后你将someData设置为dataArray,实际上将someData设置为一个空数组。我认为如果你将异步Map封装在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.log(Metadata);
        return { name: Metadata.name };
      })
    );
    console.log("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.log(someData)
      },[someData])
    */
  }
  getData();
}, []);
useFocusEffect(fetchData);

相关问题