与 MaterialTopTabNavigator 一起使用时不会触发 UseEffect

Posted

技术标签:

【中文标题】与 MaterialTopTabNavigator 一起使用时不会触发 UseEffect【英文标题】:UseEffect not triggering when used with MaterialTopTabNavigator 【发布时间】:2020-10-08 19:12:37 【问题描述】:

这是我第一次使用这个平台提问,如果我的问题似乎没有得到很好的发展,请原谅我。

简介

我想要实现的是一个动态选项卡导航器,其中选项卡的数量根据数组中的元素数量而变化,其中该数组的元素数量随时间而变化,即:


  userIds : [1,2,3,4,5,6]

将呈现一个带有 6 个选项卡的选项卡导航器

我正在使用 react-redux 来管理状态,我一直在 youtube 上关注本教程,仅供参考:https://www.youtube.com/watch?v=9boMnm5X9ak&list=PLC3y8-rFHvwheJHvseC3I0HuYI2f46oAK

上下文

在主代码 sn-p 中,动作 FetchMonthlyTransIdAct() 正在被调度,这包括 2 个按顺序调度的动作:

RequestMonthlyTransactionFetchSuccessFetchFail

(根据 FetchMonthlyTransIdAct.js 中所述,)初始状态如下,每个操作所做的更改:


  loading : false
  Id : []
  error : ''


  loading : true //when RequestMonthlyTransaction is dispatched
  Id : []
  error : ''


  loading : false // When FetchSuccess is dispatched after RequestMonthlyTransaction
  Id : [1,2,3,4,5,6]// When FetchSuccess is dispacthed after RequestMonthlyTransaction
  error : ''


  loading : false //when FetchFail is dispacthed after RequestMonthlyTransaction
  Id : []
  error : 'some error message here' //when FetchFail is dispatched after RequestMonthlyTransaction

问题

所以我目前面临的问题是,当我使用navigationContainer/tab.navigator 渲染组件时,useEffect 似乎没有触发

这是我的代码的sn-p,我已经缩小了星号之间问题的根源

const Tab = createMaterialTopTabNavigator();

const mapStateToProps = state => 
  return 
    userData: state.MonthlyEntry
  


const mapDispatchToProps = dispatch => 
  return 
    FetchMonthlyTransId: () => dispatch(FetchMonthlyTransIdAct())
  


const EntryTabNavigator = (userData, FetchMonthlyTransId) => 

  useEffect (() => 
        FetchMonthlyTransId()
  , [])
    console.log(userData.Id)

    if (userData.loading || userData.error != '') 
        return <View/>

     else 
        return( 
             **************************************************************************************
             <NavigationContainer independent = true>
                <Tab.Navigator swipeEnabled = true tabBarOptions = scrollEnabled:true, tabStyle:width:120>
                    userData.Id.map((data) => return (<Tab.Screen key = data.toString() name = data.toString() component = MonthlyTransactions initialParams=id:data.toString()/>))
                </Tab.Navigator>
             </NavigationContainer>
             **************************************************************************************
        )
    
;

export default connect(mapStateToProps, mapDispatchToProps)(EntryTabNaviga

错误消息只是没有可供选项卡导航器呈现的屏幕(因为 userData.Id 是一个空数组,而它不应该是一个空数组)

基于console.log(userData.Id)

预期的输出应该是Array [1,2,3,4,5,6] 但实际输出是Array [],这表明useEffect没有被触发

我尝试将星号之间的代码的 sn-p 替换为 &lt;View&gt;&lt;Text&gt;userData.Id&lt;/Text&gt;&lt;View&gt; 并且它能够按预期呈现(返回一个屏幕,其中数组的字符串表示形式为文本),因此让我确定星号之间的代码 sn-p 是有问题的部分。我还尝试在useEffect 中添加console.log 语句,当我在星号中有代码sn-p 时它不会向控制台输出任何内容,但是当我替换代码的sn-p 时它会输出到控制台在&lt;View&gt;&lt;Text&gt;userData.Id&lt;/Text&gt;&lt;View&gt; 之间的星号

如果已经解决了与此类似的问题,如果您能指导我,将不胜感激,如果您能指出资源以提高我对 redux 的了解(最好是初学者友好)!附加参考代码(reducer 和 action)如下

提前谢谢你

FetchMonthlyTransIdAct.js


const requestMonthlyTransaction = () => 
  return 
    type: "REQUEST_MONTHLY_TRANSACTION",
  


const fetchSucess = (ids) => 
  return 
    type: "FETCH_SUCCESS",
    payload: ids,
  


const fetchFail = (error) => 
  return 
    type: "FETCH_FAILURE",
    payload: error,
  


export const FetchMonthlyTransIdAct = () => 
  return (dispatch) => 
    dispatch(requestMonthlyTransaction())
    async function getId() 
      return require('../../data/DummyId.js').id //returns [1,2,3,4,5,6]
    
    getId().then(
      id => dispatch(fetchSucess(id))
    ).catch(
      error => dispatch(fetchFail(error))
    )

  

FetchMonthlyTransIdRed.js

const initialState = 
  loading:false,
  Id : [],
  error:''


const FetchMonthlyTransactionIdRed = (state = initialState, action) => 
  switch (action.type)
    case "REQUEST_MONTHLY_TRANSACTION":
      return 
        ...state,
        loading: true,
      

    case "FETCH_SUCCESS":
      return 
        ...state,
        loading: false,
        Id: action.payload
      

    case "FETCH_FAILURE":
      return 
        ...state,
        loading: false,
        error: action.payload
      
    default: return state;
  



export default FetchMonthlyTransactionIdRed;

【问题讨论】:

分派了哪些动作,它们对状态造成了哪些变化?如果您能指出错误发生在哪一步,将会有所帮助。 @HMR 我已经编辑了问题,请参阅上下文。为了指出哪一步出了问题,我无法确定确切的步骤,我只能按照 problem 中突出显示的内容缩小问题的根源 so the problem that I am currently facing is that useEffect does not seem to trigger 那么是什么调度所有这些动作呢?而if (userData.loading) loading 出错时为 false 但 Id 将为空数组。 如果您创建相关代码的codesanbox演示并分享链接,将很容易调试您的代码 好的,会注意并努力的,谢谢你的建议! @Yousaf 【参考方案1】:

使用 React Navigation 的 useFocusEffect,例如:

import  useFocusEffect  from '@react-navigation/native';

function Profile( userId ) 
  const [user, setUser] = React.useState(null);

  useFocusEffect(
    React.useCallback(() => 
      const unsubscribe = API.subscribe(userId, user => setUser(user));
      return () => unsubscribe();
    , [userId])
  );

  return <ProfileContent user=user />;

【讨论】:

【参考方案2】:

经过多次修补,我设法找到了解决问题的方法(或者说是变通方法)。即在 FetchMonthlyTransIdRed.js 中的初始状态的 Id 属性的数组中添加一个初始元素,这将允许导航组件的第一次呈现没有问题,然后在当FetchMonthlyTransId 被调度时,下一次重新渲染Id 然后用我导入的数组进行更新

【讨论】:

以上是关于与 MaterialTopTabNavigator 一起使用时不会触发 UseEffect的主要内容,如果未能解决你的问题,请参考以下文章

python网络编程基础(线程与进程并行与并发同步与异步)

=与==&与&&| 与 || 的区别

与 0 进行比较与与某个值进行比较是不是更快?

三.工具与市场-债券与债务股票与公司

RESTfulREST 与 RESTful 理解与实践

RESTfulREST 与 RESTful 理解与实践