繁体   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