簡體   English   中英

無法在 React Native 項目(功能組件)中重新渲染視圖

[英]Unable to re-render view in React Native project (functional component)

我目前正在學習 React。

在閱讀了文檔並嘗試了一些示例后,我仍然無法弄清楚如何使此代碼工作:

問題:

獲取數據/狀態更改后,視圖不會重新呈現。

應用程序加載最初模擬的數據,然后從服務器獲取真實數據,但盡管獲取它正確,但在使用 setCdp 時視圖不會按預期重新呈現。

需要考慮的幾點:

  1. 所有對象都被正確定義。 模擬數據正確呈現,應用程序上沒有錯誤。
  2. 所有數據都正確地從服務器到達。 Console.log() 返回所有預期數據。

代碼:

// Mock data declaration ommited...

export default function App() {
    const [cdp, setCdp] = useState(cardapio);

    useEffect(() => {
        fetch('https://ec*****.com.br/frontcontroller.php?file=getpratos.php')
            .then(res => res.json())
            .then((newState: Cardapio) => {
                setCdp({...newState}); // Doesn't seem to be working. Passing deep clone.
                console.log(newState); // Data is logged as expected.
            })
    }, [])

    return (
        <View style={styles.container}>
            <CardapioPage cardapio={cdp}/>
            <StatusBar style="auto"/>
        </View>
    );
}
// StyleSheet "styles" also omitted.

更新objectarray通常不會導致重新渲染,因為它們是引用值,如果對象沒有在return方法中使用map等高階函數傳播,則向它們添加一些內容不會導致重新渲染。

作為一個簡單的解決方案,您可以向組件添加loading狀態以在數據到達時觸發重新渲染:

function App() {
  const [loading, setLoading] = useState(true);
  const [cdp, setCdp] = useState(cardapio);

  useEffect(() => {
    setLoading(true);

    fetch('https://ec*****.com.br/frontcontroller.php?file=getpratos.php')
     .then(res => res.json())
     .then((newState: Cardapio) => {
       setCdp({...newState}); 
     })
     .catch(console.log)
     .finally(() => {
       setLoading(false)
     })
  }, [])

  return (
    <View style={styles.container}>
      <CardapioPage cardapio={cdp}/>
      <StatusBar style="auto"/>
    </View>
 );
}

現在,在組件上確實掛載了,在 API 調用之后,在finally方法中,加載設置為false 狀態值的更改將導致您的App組件重新呈現。

注意:您可以設置的初始狀態loadingfalse ,但它會導致額外的重新渲染的成分,因為在沒有安裝useEffect裝載套到true上的第一個觸發useEffect上組件並安裝。

注意:不要忘記在異步 API 調用中使用catch方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM