Let's say I have a React app (with React Router 4) with the following components and routes:
App (/)
Toolbar - A fixed toolbar
NavButton - A button whose appearance and behavior depends on the current route (see below)
MainMenu - A temporary drawer that pops out from the side to navigate between top-level routes
Admin (/admin)
Sidenav - A navigation drawer that is open all of the time on large screens and can be toggled on small screens. Clicking on items in the Sidenav navigates to different sub-routes under /admin
Content (/admin/<xyz>)
Public (/public)
Content
The behavior of the NavButton should be the following:
On a large screen:
it should always be a hamburger icon that opens the MainMenu.
On a small screen: (except for the first condition, this is similar to the experience on the Gmail mobile app)
if there is no Sidenav, it should display a hamburger icon that opens the MainMenu.
if the Sidenav is closed, it should display a back icon that opens the Sidenav.
if the Sidenav is open, it should display a hamburger icon that opens the MainMenu.
The /admin and /public routes are just examples. There are many more, some of which have Sidenavs and some of which don't.
My question is this: what is the React way to manage the UI state here and wire all of the components and routes together? It feels like App should be responsible for keeping track of whether the sidenav is open, so it can pass that information to Toolbar and others, but it also seems like App shouldn't be in charge of managing which of its potential children have or don't have Sidenavs. Also, how can props get passed down from App to some child when there's a Route in between?
Note: I'm fairly new to React and certainly not married to the component structure above; it's just for illustration.
It feels like App should be responsible for keeping track of whether the sidenav is open
True. The child components should always be presentational (pure/dumb) components.
App shouldn't be in charge of managing which of its potential children have or don't have Sidenav
I wouldn't call it "in charge". It is simply keeping the state of the application. The user is in charge, by clicking the hamburger button.
how can props get passed down from App to some child when there's a Route in between?
Why not? You can use render instead of component. For example:
let Parent = (props)=> {
<Route
path="/pizza"
render={()=> <Pizza topping={props.topping} />} />
}
Related
My issue stems from wishing to have a mobile phone rendered in the page, which mimics that of an actual phone. I would like to use components from Material UI such as AppBar and Dialog, however they do not stay confined to the container of the phone, and instead still show in the entire browser window.
When I use a Dialog Component however, it's still relative to the actual browser viewport, and not that of the "phone", such as the following:
I would like it to do what is seen in the picture below, without using an IFrame.
Is there a way I can set an anchor for the components - or at least force them to treat a specific element as their boundary? Thanks.
For those wondering if this is resolved, the solution was to roll my own Dialog and Backdrop Components with Paper, and Box components.
A ref was passed into a Box component which surrounds the entire "Phone App", and it's current Element is passed into a Mui Portal's container property.
This allows for the container of the Custom "Dialog" to be the container I wished to have things bounded by.
I would like to achieve a behavior such as this:
https://developer.android.com/training/animation/videos/layout-transition.gif
I want to have an image in one component (e.g. product card), and when i'm clicking on that component, it will switch route (e.g. product page) but will keep the same component just resize it to be bigger.
Is it possible using React DOM?
Thanks!
My overall goal is something like this for the main overarching layout component:
Live example of my goal: https://app.mobalytics.gg/
Where there is a persistent 'sticky' top bar and side bar at all stages of the application. And then from that point on I use my router to modify the white portion of the screenshot with whatever component / functionality I want the user to experience.
However I am unfortunately struggling to get this to work at all. Various attempts have resulted in navbar overlapping the sidebar and then others the sidebar overlapping the navbar, some attempts crushed the sidebar to basically be only as long as the navbar. Tried using grids and then that crushed the "white portion" when I added components through the router and a few other non-solutions sadly...
How would someone achieve this with semantic-ui-react?
Other answers I've looked at and tried to no success sadly:
1: Separating Top Nav bar and Side nav bar
2: Sidebar + Fixed Top Menu in Semantic-UI React
3: semantic-ui-react fixed sidebar and navbar: can't get sidebar and content to scroll nicely
Is there a way to delay rendering of content of dropdown/modal until it is open?
I see they are being rendered even if they are not visible until user clicks to see its contents.
The Modal component uses Portal for rendering content, while Portal renders something only if it's open. This means that the component already satisfies your conditions.
With the Dropdown component, it will be more difficult. You can control it yourself, but it means that you will need to process all events self-consciously and it will be not easy.
<Dropdown open={true} options={open && options} />
I'm using Meteor, React and Material-UI to create an app. To keep it simple, let's say that the app has two pages: home and user.
Both pages should have the same layout: an AppBar with a hamburger menu on the left and an IconMenu on the right. When the hamburger menu is selected a Drawer will slide out from the left, and when the right menu is selected a drop-down menu will appear.
For my purposes the drawer menu is static, i.e. the menu entries don't change depending on what page (home or user) is being displayed. The drop-down menu on the right, however, will change depending on what page is active, i.e. it's context-sensitive.
My question is: what options do I have in terms of building this?
I think one option is to create two page components, e.g. HomePage and UserPage, and compose each using e.g. MyAppBar and MyDrawer, plus whatever content the specific page should contain. Each page would then be responsible for creating the menu items on the drop-down menu and passing them to MyAppBar and then the entire page would be rendered.
I believe this would solve the problem, but I'm not sure if there is a better way. For instance, is there a second approach where I could update just the content component of the page and have the owning component (e.g. an ApplicationPage component) query the content component (e.g. HomeContent or UserContent) for the entries of the drop-down menu and set the drop-down menu when there's a content component change? Any other options?
I'm using React Router to do routing for /home and /user so the above must also fit in with that.
I use react router for this purpose.
<Router history={browserHistory}>
<Route component={App}>
<Route path='/login/' components={{main: Login}} />
<Route path='/confirm'
components={{
main: Confirm,
sidebar:Sidebar
}}
/>
</Route>
</Router>
In the Template App, we can then use this.props.main and this.props.sidebar as variables.
Please look at https://github.com/reactjs/react-router/blob/master/examples/sidebar/app.js form more details.