I have an application in which I am using different views for mobile and desktop instead of going for responsive design. I am using server side rendering for my application.
Here is the code for browser starter file
import React from "react";
import App from "../shared/App";
import MobApp from "../shared/MobApp";
hydrate(<BrowserRouter>{__IS_MOBILE__ ? <MobApp /> : <App />}</BrowserRouter>
Here I render 'MobApp' component in case the site is loaded on mobile and 'App' in case the site is loaded on desktop.
Here is a dummy code for 'MobApp' component
import React,{ Component } from 'react';
import Header from './views/Mobile/layouts/Header';
import './MobApp.scss';
export class MobApp extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Header />
</div>
);
}
}
export default MobApp
As it is clear I am using import for loading component level CSS. Now 'Header' component inside this has it's own CSS import.
Problem -
If someone opens the site on desktop view, the code for 'MobApp' imports like MobApp.scss and all it's child components like 'Header' is also included. As a result I am able to get the CSS of mobile components on desktop.
What all approaches can I use to avoid this?
I have read about conditional imports and will try them out but would like to know if there is something better out there.
Also, let me know if I need to change the way I am adding CSS to my components or is there a more scalable way to do the same to avoid any future problems.
Related
For example, I have 3 components==> Home, About, Contact.
Is it possible to use material ui css library for Home component, semantic ui css library for About component and bootstrap for Contact Component.
If yes, then How?
Sure you can, I think the better question is if you should.
Mixing frameworks would likely lead to in inconsistent UX. That's something normally avoided for non-technical reasons.
Still, sometimes you need to transition things slowly, and might have different parts of your software look different.
When you're certain you actually want to mix different ui frameworks, just follow the regular 'get-started' guides for those frameworks.
here's a code-sandbox with both a mui-button and a bootstrap-button
import * as React from "react";
import * as ReactDOM from "react-dom/client";
import Button from "#mui/material/Button";
import { Button as BootstrapButton } from "react-bootstrap";
import "bootstrap/dist/css/bootstrap.min.css";
function App() {
return (
<>
<Button variant="contained">Hello World</Button>
<br />
<br />
<BootstrapButton variant="primary">Primary</BootstrapButton>
</>
);
}
ReactDOM.createRoot(document.querySelector("#app")).render(<App />);
Is there any way to customize Material-UI elements with CSS sheets?
I mean, I know about the {makeStyles} method and overriding with JSS, but it looks awful in the code, and moduling it on other arcives gets confusing, I was wondering if there is any workaround to put it all together in a css archive of sorts.
You can have your makeStyles code on a separate JS file. You would typically store the object it returns in a hook called useStyles (this is what you export), and at that point you can use the hook in the relevant components.
However, If you must use raw CSS to customize your MUI components and have those custom CSS prioritized, you can opt to reorder where the MUI stylesheet is injected
The StylesProvider component has an injectFirst prop to inject the
style tags first in the head (less priority)
import { StylesProvider } from '#material-ui/core/styles';
<StylesProvider injectFirst>
{/* Your component tree. */}
</StylesProvider>
LOL I just needed some more specific Google-fu
This is how I solved it:
import React from 'react';
import ReactDOM from 'react-dom';
import { StylesProvider } from "#material-ui/styles";
import App from './App';
import './GlobalCSS.css'
ReactDOM.render(
<React.StrictMode>
<StylesProvider injectFirst>
<App />
</StylesProvider>
</React.StrictMode>,
document.getElementById('root')
);
The point is adding the tag inside your tag in index.js, and pointing your css in that same file, now you can use the predefined class names or override your class name.
I am very new to React and have recently inherited a project that was created with create-react-app. The project is partially done and I want to make the columns of a particular table adjustable (the user should drag and adjust the width). The previous developers used ant-table to create the table, which has no such feature.
I figured I could try and do this using plain js, like this fiddle: http://jsfiddle.net/thrilleratplay/epcybL4v/
However, I cannot make it work. I have included the js code as a inside index.html, have also tried calling it inside the .js file of the component.
This is my component code:
import React, {Component, PropTypes} from 'react';
import {Icon} from 'antd';
import Table from '../../components/tables/AntdTable.pg';
class SampleScreen extends Component {
render(){
return (
<Table data={this.props.availableFlavors.map(this.props.generateFruitList)}
selectRow={this.props.selectRow}
headers={this.props.tableHeaders} />
);
}
}
SampleScreen.propTypes = {
availableFlavors : PropTypes.array.isRequired,
tableHeaders: PropTypes.array.isRequired,
selectRow: PropTypes.object.isRequired,
generateFruitList: PropTypes.func.isRequired,
};
export default SampleScreen;
I am not sure if this is even possible, again, please bear with a React noob here. Any help is greatly appreciated.
Check the examples at antd website on how to create tables.
Resizable column
This is the component I am trying to render which is being mapped over and the necessary props are being dropped in. One of those props are an image that is sitting in the local directory. When i type in that same '..images/example.png' it will load with out a problem. But when this data is being mapped over and the image directory is being dropped in as the image prop, it says that it cannot find the module. Any ideas why or what I can do to remedy this?
import React, {Component} from 'react';
import {Link} from 'react-router-dom'
class Project extends Component {
render(){
let {
id,
image
}
= this.props
return(
<div className='project-container'>
<h1>{id}</h1>
<img src={require(image)} />
<p>description</p>
<p>technologies used</p>
<img src={require('../images/git.png')} />
</div>
)
}
}
export default Project;
Your image prop shouldn't contain the path to image. But just the name of the image. Then you should read the image by doing something like
<img src={require('../images/'+image)}
Make sure the variable image just has the name of the actual image and not the path.
Two possibilities I can think of.
If you have created your React app using create-react-app, then there should be a folder called public.
You need to put all your static assets (images, videos, mp3) in there.
If you have started from scratch (or from a boilerplate) using webpack, you need to import it (e.g. import Git from './img/git.png') and configure the webpack to handle PNG or other types or image files.
I have a very specific issue with Preact/React:
I have a .md file with some text, which uses react-router's <Link> tags inside for navigation. Like this:
## Heading
<Link to="/test">Let's go here</Link>
In my Component file, I render the Markdown and import the Link Component and pass the Link-components down, using the preact-markup component:
...
import {Link} from 'react-router-dom';
import text from './text.md';
import Markup from 'preact-markup';
export default class Comp extends Component {
render() {
return <Markup markup={text} components={{Link, HashLink}} />;
}
}
For importing the markdown, I use the #nuxtjs/markdown-it-loader, which works fine. It all works as expected, but doesn't feel clean.
I would like to be able to either import the Link components inside the markdown file, which would save me some boilerplate code for every view.
Or, even better, I would like to be able to write my markdown inside the Component itself, with the appropriate imports, and compile it all to HTML at build time.
I don't like runtime components since they need downloading and parse- and render time.