反应本性:在“两个底部”标签导航屏幕上使用相同的组件。
我有两个名为 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>
但是,这两个屏幕几乎彼此相同,随着 data flatlist 组件的属性的变化。这就是为什么要删除重复性,我一直在考虑在两个屏幕上使用单个组件 todos 。
当我尝试这样做时,我会注意到 todos 屏幕作为空屏幕呈现,而完成屏幕使用所需的数据正确呈现。控制台日志确实在 todos 上显示一个空数组。如果我对代码进行随机更改并保存,则在自动刷新后,我会观察到它可以正确加载数据。我正在使用路由。名称检查屏幕名称。 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>
);
};
标记区域标记区域的星(*)标记区域显示了我在屏幕上添加的最新和有问题的代码以删除重复。有帮助吗?
I have two screens named Todos and Done. I am showing them using Bottom Tab Navigator.
<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>
But these two screens are almost identical to each other with a change in the data property of FlatList component. That's why to remove duplicity I was thinking to use a single component Todos on both screens.
When I was trying to do that I notice Todos screen renders as an empty screen while the Done screen renders properly with the desired data. The console log indeed shows an empty array on Todos. If I make a random change in the code and save it, then after the automatic refresh I observe that it loads the data correctly. I am using route.name to check the screen name. The code for Todos screen is as follows:
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>
);
};
The star (*) sign marked area shows the newest and problematic code that I added on the screen to remove duplicity. Any help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这似乎是一个渲染错误。 (在更改选项卡时,组件不会再次呈现)
一个可能的解决方案可以是验证使用效率并设置状态的路由,因此,每当状态更改时,组件将重新渲染
我们将使用该状态在LOADTODOS函数中验证
This seems to be a render error. (the component isnt rendering again when the tab is changed)
A posible solution could be to validate the route in the useEffect and setting a state, therefore whenever the state changes the component will re-render
and we will use the state to validate in loadTodos function
我通过在 loadtodos 方法上用parsedtodos替换TODOS来解决此问题。我想初始渲染时,空的redux商店托多斯(Todos)并未在dispatch上的parsedtodos(setalltodo(parsed))的数据填充。它将空存储转移到了过滤器方法。这就是为什么屏幕空白的原因。我的固定代码:
I have fixed this problem by replacing todos with parsedTodos on loadTodos method. I guess on initial render the empty redux store todos was not populated with the data from parsedTodos on dispatch(setAllTodo(parsed)). It passed empty store to the filter method. That's why the screen was blank. My fixed code: