反应原生:在两个"Bottom Tab Navigation Screens"上使用相同的组件



我有两个屏幕名为Todos. 我正在向他们展示如何使用底部标签导航器。

<Tab.Navigator
screenOptions={({route}) => ({
headerShown: false,
tabBarIcon: ({focused, color, size}) => {
let iconName = '';
size = focused ? 25 : 20;
if (route.name === 'To-Do') {
iconName = 'clipboard-list';
} else if (route.name === 'Done') {
iconName = 'clipboard-check';
}
return <FontAwesome5Icon name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: '#0080ff',
tabBarInactiveTintColor: '#777777',
tabBarLabelStyle: {fontSize: 15, fontWeight: 'bold'},
})}>
<Tab.Screen name="To-Do" component={Todos} />
<Tab.Screen name="Done" component={Done} />
</Tab.Navigator>

但是这两个屏幕几乎是相同的,只是改变了数据FlatList的属性组件。这就是为什么我想使用单个组件Todos来消除重复的原因。在两个屏幕上。

当我试图这样做的时候,我注意到Todos屏幕显示为空屏幕而屏幕正确呈现所需的数据。控制台日志确实在Todos上显示了一个空数组。. 如果我做一个随机修改代码并将其保存,然后我观察到它的自动刷新加载数据正确。我正在使用route.name来检查屏幕名称。Todos代码屏幕如下:

import stuff...
...
const Todos = ({navigation}: TodosPageProps) => {
const dispatch = useAppDispatch();
const {todos}: {todos: TodoInterface[]} = useAppSelector(
state => state.todoReducer,
);
const route = useRoute<RouteProp<RootTabParamList, 'To-Do' | 'Done'>>();
const [data, setData] = useState<TodoInterface[]>([]);
useEffect(() => {
loadTodos();
console.log('bruh');
}, []);
const loadTodos = () => {
AsyncStorage.getItem('todos').then(fetchedTodos => {
const parsedTodos: TodoInterface[] = JSON.parse(fetchedTodos || '[]');
dispatch(setAllTodo(parsedTodos));
// *************************** START *************************************
if (route.name === 'To-Do') {
const filteredData = todos.filter(todo => todo.done !== true);
console.log('aisi', filteredData);
setData(filteredData);
} else if (route.name === 'Done') {
const filteredData = todos.filter(todo => todo.done === true);
setData(filteredData);
}
// *************************** END *************************************
});
};
... some other methods
...
return (
<HideKeyboard>
<View style={styles.body}>
<FlatList
data={data}
...other props
...
/>
</View>
</HideKeyboard>
);
};

星号(*)标记的区域显示了我在屏幕上添加的最新和有问题的代码,以消除重复。任何帮助吗?

这似乎是一个渲染错误。(当TAB改变时,组件不再呈现)

一个可能的解决方案是在useEffect中验证路由并设置状态,这样当状态改变时,组件就会重新呈现我们将使用状态来验证loadTodos函数

import React from 'react'
export const LoadTodos = () => {

const [selectedPage, setselectedPage] = useState('Done')

useEffect(() => {
if (route.name === 'To-Do' && selectedPage === 'Done'){
setselectedPage('To-Do')
}
if (route.name === 'Done' && selectedPage === 'To-Do'){
setselectedPage('Done')
}
console.log('bruh');
}, []);

const loadTodos = () => {
AsyncStorage.getItem('todos').then(fetchedTodos => {
const parsedTodos: TodoInterface[] = JSON.parse(fetchedTodos || '[]');
dispatch(setAllTodo(parsedTodos));

// *************************** START *************************************
if (selectedPage === 'To-Do') {
const filteredData = todos.filter(todo => todo.done !== true);
console.log('aisi', filteredData);
setData(filteredData);
} else if (selectedPage === 'Done') {
const filteredData = todos.filter(todo => todo.done === true);
setData(filteredData);
}
// *************************** END *************************************
});
};
return (
<HideKeyboard>
<View style={styles.body}>
<FlatList
data={data}
...other props
...
/>
</View>
</HideKeyboard>
)
}
export default loadTodos

我已经通过在loadTodos上用parsedTodos替换todos解决了这个问题方法。我猜在初始渲染时,空的redux存储todos没有使用调度时parsedTodos的数据填充(setAllTodo(parsed))。它将空存储区传递给过滤器方法。这就是为什么屏幕是空白的。我的固定代码:

const loadTodos = async () => {
const fetchedTodos = await AsyncStorage.getItem('todos');
const parsedTodos: TodoInterface[] = JSON.parse(fetchedTodos || '[]');
if (parsedTodos.length !== todos.length) {
dispatch(setAllTodo(parsedTodos));
}
// *************************** START *************************************
if (route.name === 'To-Do') {
const filteredData = parsedTodos.filter(todo => todo.done !== true);
setData(filteredData);
} else if (route.name === 'Done') {
const filteredData = parsedTodos.filter(todo => todo.done === true);
setData(filteredData);
}
// *************************** END *************************************
};

相关内容

最新更新