Creating Different mobile layout for a component in ReactJs - reactjs

How can we create a completely different (mobile type layout) for a component (having a different desktop type layout) using ReactJs.
(Not Responsive , responsive is something css has to take care of.)
It should be different layout for the component i.e here Creating a page with a menu(header menu) for desktop screens which becomes a navigation sidebar with logo on small screen.

Honestly, a simple resposive css layout may be the best solution, but the steps are to
1) Detect in JS if user in on mobile or desktop. For example this question has a good suggestion as an answer: Detecting a mobile browser
2) Use it to decide in your root component that which layout to use:
function isMobile() {
// some js way to detect if user is on a mobile device
}
class Root extends Component {
render() {
return isMobile() ? ( <MobileLayout /> ) : ( <DesktopLayout /> )
}
}

Checkout react-responsive, You can use media query to render different component depending on device size.

Related

How to define minimum supported screen size with MUI/ReactJS?

I am using Material UI 5.6 in a webapp that requires large viewport. I want to define a minimum screen width for the entire app such that:
If users access the app on devices with smaller width, the app should not resize beyond the defined minimum width.
If users access the app on devices with smaller width, show them a warning message that we dont fully support their device.
Is this achievable with MUI, or I need another library for this?
The first requirement is achievable through styling and media-queries and can be achievable either with plain CSS or with MUI-specific styling tools.
The second requirement can be implemented with useMediaQuery hook in several ways:
Restrict users with unsupported devices to use the app
You can wrap the entire app in a wrapper-component where you define the required min-width
const requiredWidth = useMediaQuery("(min-width:1024px)");
Then you can return UI of your App or the screen with a message that the device is not supported:
return requiredWidth ? (
{ children }
) : (
<p>We do not fully support your device </p>
);
In this case, the entire app will be unavailable for the user.
Show an alert
Another option is to use the same wrapper component and render an Alert or Snackbar which will be rendered alongside the rest of the UI of your app :
return (
<>
{children}
{requiredWidth && <AlertComponent />}
</>
);
In this case, a user will be notified about their device but still be able to use the app.

How should I use React Router to swap out what I want to display in my header, body and footer?

From my understanding, React Router is good for when you want to reuse a container and different routes will change what's displayed inside of the container. However, I want it such that a route will change what's displayed in multiple containers.
For example, in my login page, I have my login form in the body container and my link to registration in the footer.
In my registration page, I have my registration form in the body and the link to login in the footer.
In my home page, I have a welcome message in the body and some buttons to change tabs in the footer.
What's the best practice for the component structure involved in this?
the best practice of React is making reused-components that help not to waste your time in coding, just only pick and reuse components in many different scenarios.
Base on your example, in login page and registration the footer may have the same design but only the links is different. We can create a layout named LinkInFooter and receive an array link objects to displayed:
// file /pages/login.js
<PageLayout>
<LoginComponent/>
< LinkInFooter links={[url: '/registration', label: 'registration page']}/>
</PageLayout>
// file /pages/registration.js
<PageLayout>
<RegistrationComponent/>
<LinkInFooter links={[url: '/login', label: 'login page']}/>
</PageLayout>
Below is a few tips for you:
Should have a WrappedLayout for all pages, I don't say it should be the same layout for all pages but it should have the same layout for many pages. That WrappedLayout will make your page look consistent when change route or hide / show chilren components.
Layouts/*.js : Layout directory is the place that hold all your custom small components that you want they are displayed same across your projects. For example: I customized a Select component that allow to search item, select multiple items... So that I create an custom <Select/> layout to replace html's <select/> on my project.
Components/*.js: this one hold all your components, either reusable or non-reusable. A component can be made by compose many others components: what can be reuseable should be created a new file for it and import to use. If not, create an internal component is enough.
Pay 5 minutes on UI design before start. Use the initial time to imagine the structure of pages then answer these questions :
How many component should I have for this pages?
Could be reused frequently?
Which items on the design should be layout?

Switching Layouts Based on Screen Size in Gatsby

I am building a web app using Gatsby that needs to load a separate layout built using mobile ui library in mobile browser and different layout with another ui library when opening in desktop browser.
How should I achieve this at the root (app) component level?
Thank you
I think you can experiment with wrapPageElement in gatsby-browser.js and gatsby-ssr.js, returning different layout based on browser height:
const React = require("react")
const Layout = ...
const MobileLayout = ...
exports.wrapPageElement = ({ element, props }) => {
// a made up hook to detect browser size, implement your own
const isMobile = useDetectMobile()
return (
isMobile
? <MobileLayout {...props}>{element}</MobileLayout>
: <Layout {...props}>{element}</Layout>
)
}
This get tricky though, because during server-side generation you'd need a default layout, which may (or may not?) lead to faulty behavior? I'm not sure.
A safe bet is to generate a mobile version & a desktop version for your app, then detect browser size / type in gatsby-browser & redirect accordingly.

Semantic-UI-React Responsive component renders element in spite of minWidth/maxWidth prop

I have a component where I want to render different components based on screen size. If I reload the page while on mobile view, everything is ok, NavBarMobile is rendered and NavbarDesktop is not.
If I reload the page while on desktop view, then my NavbarMobile is rendered again instead of NavBarDesktop.
If I start resizing the screen to mobile and back to desktop view, NavBarDesktop is rendered correctly.
So, the problem is first page load while in Desktop view, how to fix that?
const { mainAppComponents, } = this.props
const { visible, } = this.state
return (
<Fragment>
<Responsive maxWidth={767}>
<NavBarMobile
onPusherClick={this.handlePusher}
onToggle={this.handleToggle}
rightItems={rightItems}
visible={visible}
>
{mainAppComponents.header}
{mainAppComponents.routes}
</NavBarMobile>
</Responsive>
<Responsive minWidth={768}>
<NavBarDesktop rightItems={rightItems}>{mainAppComponents.header}</NavBarDesktop>
{mainAppComponents.routes}
</Responsive>
</Fragment>
)
Igor-Vuk, I put together a quick codesandbox example just to make sure there was not a problem with how you are trying to implement the min/max width props. As you can see from this example, they do in fact work as expected. https://codesandbox.io/s/98pk46l7vr
Without seeing the rest of your component, or application, the issue may be due to something in your router. I'd recommend trying to remove some of the other components you are returning as children of the Responsive component to see if it starts working as expected (like in my codesandbox example). If it works, then you know the problem is somewhere in the children. If it does not work then there is a greater problem above in your app.
If you are using SSR, on initial load the content was rendered and served with the Responsive component having no knowledge of the viewport. So you may need to also add a CSS media query.

How to import a component or file in React using variables?

I'm building a web app using React that shows the blueprint for the building you select, in an already selected campus.
I have a "Content" component that loads the campus or building map, depending what you chose.
The "BuildingMap" component needs to load a specific blueprint according to what building you selected. It gets the props.building with the name of the building but I don't know how to load a component using that variable.
I have tried import, fetch and require but nothing seems to work.
Please help.
My code looks something like this:
//Content Component
<BuildingMap building={selectedBuilding} campus={selectedCampus} />
//BuildingMap Component
import *MyBlueprint* from (specific folder depending on the campus selected)
class BuildingMap extends React.Component {
render(){
return (
<div className="blueprint" id={this.props.building}>
{*MyBlueprint*}
</div>
)
}
}
Unfortunately, you cannot import/require components dynamically in React environment.
Depending on how many buildings/blueprints there are, it's possible to import them one by one, create component-building map and pick component by building ID.
If there are many/infinite components to load, I would surely pick another method - don't know content of your problem.
import BlueprintA from './BlueprintA'
import BlueprintB from './BlueprintB'
import BlueprintC from './BlueprintC'
// ...
class BuildingMap extends React.Component {
render(){
const C = {
buildingA: BlueprintA,
buildingB: BlueprintB,
buildingC: BlueprintC,
// ...
}[this.props.building]
return (
<div className="blueprint" id={this.props.building}>
<C />
</div>
)
}
}
This question is pretty old but as I was looking for how to solve the same problem let me give my answer. It can be done with dynamic import React.lazy:
const OtherComponent = React.lazy(() => import('./OtherComponent'));
See more details here: https://reactjs.org/docs/code-splitting.html#reactlazy
To add to #Andreyco's answer:
Using a lookup table of string IDs/names to component classes is a typical React idiom. One common use case is a modal manager component that can render multiple different types of modals. For some examples, see Dan Abramov's answer at "How can I render a modal dialog in Redux?" (not Redux-specific), as well as some of the related articles in the React Component Patterns#Modal Dialogs and Redux Techniques#UI sections of my React/Redux links list.
Per #azium's comment: it is definitely possible to use dynamic importing (via require.ensure() or the new import() function) to load chunks at runtime, and you could add the exports from those dynamically imported chunks into a lookup table when they are loaded.

Resources