与 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 个按顺序调度的动作:
RequestMonthlyTransaction
→ FetchSuccess
或 FetchFail
(根据 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 替换为
<View><Text>userData.Id</Text><View>
并且它能够按预期呈现(返回一个屏幕,其中数组的字符串表示形式为文本),因此让我确定星号之间的代码 sn-p 是有问题的部分。我还尝试在useEffect
中添加console.log
语句,当我在星号中有代码sn-p 时它不会向控制台输出任何内容,但是当我替换代码的sn-p 时它会输出到控制台在<View><Text>userData.Id</Text><View>
之间的星号
如果已经解决了与此类似的问题,如果您能指导我,将不胜感激,如果您能指出资源以提高我对 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的主要内容,如果未能解决你的问题,请参考以下文章