-
Notifications
You must be signed in to change notification settings - Fork 113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issues with Dynamic Tabs using a slug #522
Comments
I was able to come up with a solution. There's likely a better way to do this and needs error handling, but it's working for my needs. I added a slug param to the Tab Screen options and set the name as the title, which is unique for each tab. Then modified So far it seems to work with out issues for me, and with complexity of using nested navigators both a drawer and tabs. I'm sure someone can make this better. It's a starting point at least. tabs/_layout.tsx export default function TabsLayout(){
const [tabs,setTabs] = useState([])
useEffect(()=>{
//fetch whatever data for each tab
setTabs([{id:1,title:'tab1'},{id:2,title:'tab2'},{id:3,title:'tab3'}]);
},[]);
return(
<Tabs>
{tabs.map((tab,index)=>{
return(
<Tabs.Screen
key={tab.id}
name={tab.title}
options={{href:`tabs/${tab.id}`,title:tab.title,slug:'[tabs]'}}
/>
)
})}
</Tabs>
)
} expo-router/src/useScreens.tsx const ordered = order
.map(({ name, redirect, initialParams, listeners, options },index) => {
if (!entries.length) {
console.warn(
`[Layout children]: Too many screens defined. Route "${name}" is extraneous.`
);
return null;
}
let matchIndex = entries.findIndex((child) => {return(child.route === name || child.route === options?.slug)});
if (matchIndex === -1) {
console.warn(
`[Layout children]: No route named "${name}" exists in nested children:`,
children.map(({ route }) => route)
);
let dynamicChild = {...children[children.findIndex((child)=>{return(child.route === options?.slug)})],route:name? name : `dynamicScreen${index}`};
entries.push(dynamicChild);
matchIndex = entries.findIndex((child) => {return(child.route === name || child.route === options?.slug)});
}
if(matchIndex >= 0) {
// Get match and remove from entries
const match = entries[matchIndex];
entries.splice(matchIndex, 1);
// Ensure to return null after removing from entries.
if (redirect) {
if (typeof redirect === "string") {
throw new Error(
`Redirecting to a specific route is not supported yet.`
);
}
return null;
}
return { route: match, props: { initialParams, listeners, options } };
}
})
.filter(Boolean) as {
route: RouteNode;
props: Partial<ScreenProps>;
}[]; |
Is the below issue similar or different? |
hey mate, did you make any progress on this ? facing a similar issue |
@EvanBacon Thanks for this awesome library. Is there any specific reason to restrict this kind of implementation as it's working fine with react-navigation. I'm trying to migrate my old expo app to use expo-router and this is a blocker for me. |
Same issue here - wondering if I'm missing something or anyone has figured out a workaround! - would like to have:
|
same issue, trying to make dynamic tabs from api. does someone find any working solution? |
I am not sure this use case is supported. You can add a Tab.Screen for a corresponding file in the same directory as the |
Same issue here, trying to build a tab navigator only on one route, and link to that route with a search param, them use that param to generate the tabs. User sees mural of notes -> user clicks to a note and navigates to /note with id param -> user sees a tab navigation with a screen to edit that note and a screen to view the rendered markdown version of that note. All works fine except tabs dont show.
|
Any progress on this one? I also need this feature |
This repo is not maintained you need to check expo/expo |
I have the same problem but i am using the allCustomerTypes.forEach((value, index) => {
tabList.push(
<TopTab.Screen
name={value.text}
component={CustomerListScreen}
options={{title: value.text}}
initialParams={{ customerTypeList: [value.code] }}
key={index.toString()}
/>,
);
}); It works but the URL gets really weird: http://localhost:8081/xxx?customerTypeList=yyy&screen=zzz¶ms=%5Bobject+Object%5D |
I am using material-top-bar too. I didn't know about |
This repo is in maintenance mode and is only used for critical issues for v2. Its not being actively monitored for issues / support. Expo Router uses the React Navigation Tabs navigator, which as people have noted only allows tabs with unique names. We are aware of this restriction but it is not high on the roadmap (there are bigger bugs/features). The work around is to create your own custom navigator or implement a There is an example here: expo/expo#27377 (comment) |
@ansmlc Do not need create "{value.text}.jsx/tsx" files. In my case, Just a |
Not sure if this helps you but I'm using the example custom "tabBar" from Material Top Tabs docs. This way you can navigate without needed to use the "href" prop at all. For me, I can't use the component prop like
And yeah, expo-router seems to bring more problems than it solves. It's ridiculous they consider this an "edge case". |
imo this issue defeats the whole purpose of having slug pages. |
I created a patch for router v3.4.9. Clone the repo and replace contents of node_modules/expo-router. |
This example wasn't great, but the one below actually is very close to a standard tab bar navigator. I massaged it a bit and it is behaving like a standard tab navigator but allows reusing routes for each tab. https://github.com/EvanBacon/expo-router-layouts-example/blob/main/app/slot/_layout.tsx
|
Is anyone found a solution for this? |
Which package manager are you using? (Yarn is recommended)
npm
Summary
What I am trying to do is to use a slug and render different tabs depending on a users specific configuration.
It seems in React Navigation, the name property in Tabs.Screen must be unique, and so it doesn't play nice with slugs and throws the following error: Screen names must be unique: [tab],[tab],[tab]
The goal is to use one slug file for multiple tabs.
Minimal reproducible example
app
->(home)
-->tabs
--->_layout.tsx
--->[tab].tsx
_layout.tsx
The text was updated successfully, but these errors were encountered: