【问题标题】:Tab.Screen does not re-renderTab.Screen 不会重新渲染
【发布时间】:2021-12-30 19:14:31
【问题描述】:

data 应该在 useEffect 运行时更新,并且确实如此。但是,此更改不会导致 Tab Navigator 的 Liked 页面重新呈现,它作为 route.params 参数传递。

为什么不重新渲染?

下面是父组件 Home.js,它有一个 Tab.Navigator 作为子组件。我将注释data 的数据传入标签导航器的videoData 初始参数。但是,当我更新data 时,videoData 也永远不会更新。

Home.js

  const [data, setData] = useState([{name: 'test'}]);
  console.log('DATA', data);
  // {lastVisible} for keep track of firebase paging
  const Tab = createMaterialTopTabNavigator();
  const navigator = 
  <Tab.Navigator>
  <Tab.Screen name="posts" component={FeedList} initialParams={{videoData: route.params.videoData}} />
  <Tab.Screen name="Liked" component={FeedList} initialParams={{videoData: data, test: 'helloworld'}} />
</Tab.Navigator>;

  useEffect(()=>{
    fetchChatGroups().then((ar) => {
      setData(ar);
    });
   },[]);

...
return <>{navigator}</>

initialParams 是否不受父组件的 useState 变量重新渲染的影响?当我在 FeedList 中打印 route.params.videoData 的值时,我得到以下信息:

[Sat Jan 02 2021 19:54:41.145]  LOG      [{"name":"test"}]

这意味着状态保持为默认状态,即使我通过控制台打印确认状态确实改变了这一行:console.log('DATA', data);

【问题讨论】:

  • 只有当你在 useEffect 依赖数组 useEffect(()=&gt;{ //you logic},[data])987654331@ 中提到状态时才会重新渲染
  • 感谢您的评论。不过,不是这样。仍然没有更新。
  • 你可以使用var而不是const,看看它是否在const navigator中工作
  • 它没有改变任何东西:(
  • 你最终能解决这个问题吗?

标签: reactjs


【解决方案1】:

尝试将这行代码const Tab = createMaterialTopTabNavigator();移到组件外或用useMemo包裹。

【讨论】:

  • 没用。不过是个好主意。没有意识到我每次渲染都在制作一个新的标签导航器
  • 你能用setParams代替传递道具吗?我认为 initialParams 跳过重新渲染。
  • 我如何在这里使用 setParams?我还没有访问导航器的权限。你可以用你的意思编辑你的答案吗?谢谢`
【解决方案2】:

我的答案是 Tab.Screen 在状态值更改时重新渲染,我认为这可能会对您有所帮助。

查看此堆栈流以获取更多信息: [博客]:React native: React navigation tab screen does not update if children is not an inline function

所以,为了重新渲染组件,我们需要将 props 作为子组件传递给组件。 示例:

<Tab.Screen name="posts" component={FeedList} />

这里不用component={FeedList},你可以用children =>

<Tab.Screen name="posts" children={()=>this.FeedList(Pass Props Here)} />

上面的例子是类组件。

其他例子:

 // Inside render()
 <Tab.Screen
    name="Account"
  //component={this.AccountScreen}
    children={() =>
      this.AccountScreen(this.props.schoolInformationPending)
    }
    options={{
     tabBarLabel: 'Account',
    }}
  />

// Inside Class Component
 AccountScreen = (props: any) => {
    return (<View><Text>{props.value}</Text></View>)
 }

【讨论】:

    猜你喜欢
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 2020-04-18
    • 2018-09-01
    • 2022-01-06
    • 2020-09-27
    相关资源
    最近更新 更多