【问题标题】:UseEffect not triggering when used with MaterialTopTabNavigator与 MaterialTopTabNavigator 一起使用时不会触发 UseEffect
【发布时间】: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

标签: reactjs react-native react-redux react-navigation use-effect


【解决方案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 然后用我导入的数组进行更新

    【讨论】:

      猜你喜欢
      • 2021-09-24
      • 2023-01-03
      • 2021-04-09
      • 1970-01-01
      • 2021-07-03
      • 2021-10-25
      • 1970-01-01
      • 1970-01-01
      • 2021-08-25
      相关资源
      最近更新 更多