如何在 react-native 中重新渲染组件?

Posted

技术标签:

【中文标题】如何在 react-native 中重新渲染组件?【英文标题】:How to re-render componenets in react-native? 【发布时间】:2021-01-02 09:43:16 【问题描述】:

我是 react-native 开发的新手,已经为这个问题花了 2 天时间。我不擅长打字,但我可以用我的源代码解释问题。

当前情景:

    应用主屏幕: 有用于停靠特定卡的停靠图标。单击停靠图标后,该卡作为停靠列表存储在数据库中。它工作正常。

    在主屏幕上有诸如切换到 Docklist 的链接: 当我点击停靠列表时,它会在停靠列表屏幕上重定向,一切正常。

    在 DockList 屏幕上有 4 个卡片,例如“Card a”、“View Docklist”、“Card c”、“Card d”

在此屏幕上执行的步骤:

    componentDidMount() 在 componentDidMount() 上,我从 AsyncStorage(Local Storage) 获取“ID”并将该值设置为状态。我正在将此 ID 传递给 api 参数。 调用服务器 API (this.viewDockList())

问题领域:

根据我的知识和研究,componentDidMount() 在渲染后只调用一次。 随时点击“查看DockList”需要调用api。 在这里,当我刷新应用程序时,以下场景正在运行

    主屏幕->我从主屏幕插入了一张卡片

    在主屏幕上 -> 点击“切换到 DockList” -> 导航到 Dock 屏幕

    在 Dock 屏幕上 -> 单击“查看 Dock 列表” -> 第一次调用 api 并按照我的要求显示数据。

    现在,我回到主屏幕,再次停靠卡并导航到停靠屏幕并单击查看停靠列表,Api 没有调用,只有 render() 正在调用。这里我需要再次调用 API 并从服务器获取最新数据。我试图在单击“查看停靠详细信息”时调用强制更新,调用了 api 但列表未更新。

这是我的源代码:

componentDidMount() 
    console.log("ComponentDidmount called")

    AsyncStorage.getItem('Id').then(value => 
        if (value !== null) 
            this.setState( profileId: value )
        
    )

    this.getDockedData();


 getDockedData = async () => 

    this.showLoading();

    console.log("API CALLED=====")

    try 
        let axiosConfig = 
            headers: 
                'Access-Control-Allow-Origin': '*'
            ,
            params: 
                pId: this.state.profileId,
            
        

        axios.get('apiendpoint', axiosConfig)
            .then((res) => 

                this.setState(
                    sourceData: [...res.data.filter((item) =>  if (!item.s_updated && !item.b_updated && !item.p_updated) return item )],

                );
                console.log("Data from dock api====", this.state.sourceData)
                this.hideLoading();
            )
            .catch((err) => 
                console.log("AXIOS ERROR WHILE GETTING DOCK DATA: ", err);
                this.hideLoading();
            )
    

    catch (error) 
        console.log("ERROR======", error);
        this.hideLoading();
    


   forceUpdate() 
    console.log("Force update called===")
    this.getDockedData();
     

//On render I am calling component 
 <Dockcomp  description="Lorum ipsum" onButtonPress=() => this.props.navigation.navigate('dockdetailscreen',  item: sourceData, type: "docked", UpdateUI: this.UpdateUI , this.forceUpdate()) />

预期响应:

    主屏幕->我从主屏幕插入了一张卡片 在主屏幕上 -> 点击“切换到 DockList” -> 导航到 Dock 屏幕 在 Dock 屏幕上 -> 点击“View Dock List” -> 每当我点击 View Dock list 时,应该调用 api。现在它只调用一次,因为我使用了 componentDidMount()

提前非常感谢您!过去两天我真的为这个问题而苦苦挣扎。

【问题讨论】:

【参考方案1】:

您不需要重新渲染。一旦组件获得焦点,您可以编写一个侦听器来触发 getDockedData。像这样:

componentDidMount() 
    this.unsubscribe = navigation.addListener('focus', () => 
      // stuff you are already doing in componentDidmount
    );
  

  componentWillUnmount() 
    this.unsubscribe();
  

你可以了解更多关于监听器和导航事件here

【讨论】:

【参考方案2】:

React 和 React-Native 使用 shadowDOM 来评估何时触发重新渲染。除非强制,否则仅当组件的 stateprop 更改时才会发生重新渲染。此时,在 Tree 中进行浅层比较以查看是否需要重新渲染。所以如果你想调用重新渲染,你可以在componentDidMount中添加一个监听器来触发状态改变。或者其他任何地方。

【讨论】:

以上是关于如何在 react-native 中重新渲染组件?的主要内容,如果未能解决你的问题,请参考以下文章

为啥组件在状态更改后不重新渲染。在 react-native 函数组件中

道具更新时重新渲染组件(使用 Redux)

ScrollView 在 react-native 中渲染没有数据的更新组件?

子组件不会重新渲染,但父组件会重新渲染。如何让子组件重新渲染?

如何在组件 React / React-native 的单独页面中使用动态 graphql(字符串)

如何在 Angular 2 中强制组件重新渲染?