The switch component Blueprint (demo and documentation here) displays no border when selected/unselected. I included this component in a React component as follows:
import {Component} from "react";
import {Switch} from "#blueprintjs/core";
import React from "react";
class BPrintMain extends Component{
render(){
return (
<Switch id="switch-input-3" label="Public" disabled={false} />
)
}
}
export {BPrintMain};
When I click the switch component, it displays a border as follows:
The border remains until the focus is lost, that is, I click on something else on the page.
I am including the Blueprint css files from the css of my main componeent as follows:
#import "~#blueprintjs/core/lib/css/blueprint.css";
#import "~normalize.css";
#import "~#blueprintjs/icons/lib/css/blueprint-icons.css";
The css appears to be working for buttons, input controls etc. What am I missing? Why is the switch displaying that focus/bounding box on focus?
Ok, I found the answer. Leaving it here in case someone else gets bitten by this and uses my choice of words for expressing the problem.
As explained in this github issue this is expected behaviour of browsers: display the element with focus. As the answer in the issue says, simply adding the following two lines to your app (I did it in index.js, the root of my React app) solves the problem:
import { FocusStyleManager } from "#blueprintjs/core";
FocusStyleManager.onlyShowFocusOnTabs();
Related
I think this question may expand beyond React, but I'm still not sure if React itself is responsible for the problem.
The environment is React with TypeScript. I use CSS imports in the component files, so that each component has its specific stylesheet and I presume that those styles will not be added to the <head> element until the respective component is instantiated. But it turns out that if I import a component from a file, which just reexports all of them, the styles of all the other components, which I do not use, are still added in the DOM.
Here is a simple example, let's say I have two simple components in the lib folder - Avatar and Button. They look like this (the Button is similar):
import React from 'react';
import './avatar.css';
const Avatar: React.FC = (props: any) => {
return (
<div className="avatar">
{props.children}
</div>
);
}
export { Avatar };
Then I add index.ts to reexport the components, in order to have simple import path:
import { Avatar } from './Avatar';
import { Button } from './Button';
export { Avatar, Button };
And finally, in my AppComponent I want to use only the Button component:
import React from 'react';
import { Button } from './lib';
const App: React.FC = () => {
return (
<div className="App">
<Button>example</Button>
</div >
);
}
export default App;
To my surprise, in the <head> element there are <style> tags not only for the Button, but also for the Avatar. Why is this happening? Is my reexport configuration wrong?
Notice that if I import the component directly from its file - import { Button } from './lib/Button' I do not get the Avatar styles.
The example is really simple, but the real scenario is related to a React component library, which contains a lot of components with a lot of stylesheets. I want to avoid inserting so many <style> tags in the DOM, unless they are really needed.
Thank you for spending time on this!
so that each component has its specific stylesheet and I presume that those styles will not be added to the element until the respective component is instantiated
This presumption is wrong. React uses webpack to bundle its files and the way webpack works for CSS imports is that it loads all the CSS files that your project depends on and put them in the <head> element right at the beginning.
You might ask: Then how do I keep my styles separated and don't get them mixed.
There are three solutions to this
A good way is to Add a CSS Modules Stylesheet
Another suggestion is to make the <div> that wraps your component have a className that is the same name as the component so your component will look like this
export default class ComponentOne extends Component {
...
render() {
return(
<div className="ComponentOne">
...
</div
)
}
}
And your component CSS file will look like:
.ComponentOne div img {
...
}
.ComponentOne .class-one {
...
}
With this way, using CSS preprocessor like SASS will come in handy, so your .scss file will simply begin with:
.ComponentOne {
...
}
Another solution is to have the styles as an object inside your component. This way the style will only be scoped to your component and will be removed when the component unmounts, but then you will lose the ability to easily create #media queries andother special effects like:hover` plus this approach is not recommended for small components that get mounted and unmounted too often because this creates a performance issue once the application gets larger
You also might ask: since all the style sheets get imported at the begging, then why don't I put all my styles in one big style sheet and not splitting them up.
Other than the fact that splitting your styles will make them easy to handle so that each component will have its separate CSS file and webpack will handle importing them, There is one other benefit:
Say you have a feature1 component which also has a feature1.css file. In the beginning, when you have feature1 imported in your main app, webpack will also import its style sheet and put it in the <head> element.
But say in the future you decided you don't want to use feature1 component anymore and you are using another feature2 component now which has its own feature2.css file. Now since no other component is importing feature1 component, webpack will also ignore importing feature1.css into the <head> element.
I'm trying to embed a tockify calender into a component, within a react project I'm building. I should note that I'm using a library called react-script-tag that allows me to use <script/> tags within my component.
Anyway, the calender is rendering - but then keeps on re-rendering as if it's stuck in some sort of loop. I have a feeling I need to implement some sort of lifecycle method. Any suggestions? Code as follows:
import React from 'react'
import Nav from './Nav'
import ScriptTag from 'react-script-tag'
class Events extends React.Component {
render() {
return (
<div>
<Nav/>
<div data-tockify-component="calendar" data-tockify-calendar="hzevents2"></div>
<ScriptTag isHydrating={false} data-cfasync="false" data-tockify-script="embed" src="https://public.tockify.com/browser/embed.js"></ScriptTag>
</div>
)
}
}
export default Events
Use React.PureComponent instead of React.Component because of React.PureComponent will prevent to re-rendering if there is no need or update.
The documentation of 'react-script-tag' says
It is recommended that the Script tag is placed in a component that
only renders once in the entire life of your app. Otherwise, a new
tag will be appended each time the component mounts again.
There are plans down the road to prevent this.
You may want to use a pure component to prevent rerendering.
Edit: Regardless of my answer you should show the rest of your code to be able to detect the problem.
I want to implement modals within my React app. Portals seems to be quite nice for this but I don't want to change my outer HTML-structure.
The HTML-should still be:
<div id="app"></div>
I don't want to add an additional div to the HTML-structure.
In the App.js I tried to add the root-modal-container like this:
class App extends Component {
render() {
return (
<ResponsiveProvider>
<div id="root-modal"></div>
<Modal>
<div>Modal :-)</div>
</Modal>
</ResponsiveProvider>
);
}
}
But when trying to getElementById in the Modal-component I always get the error: appendChild on null...
The problem is, that the root-modal-div isn't renderend when initiating the Modal-component.
Any solutions how I can render Modals right in the level after from anywhere in my app?
You can see the not-running-code here. Uncomment the second line in HTML to get the code running.
You can do this with React portals, but it's a little awkward, and you have to get quite involved with the DOM itself to render across an app like this (rather than to totally external DOM nodes).
I've just released a library to fix this exact problem, since although it's possible with portals, it's not easy.
You can see the full details at https://github.com/httptoolkit/react-reverse-portal.
In your example, a solution would look something like:
import React from "react";
import ReactDOM from "react-dom";
import * as portals from "react-reverse-portal";
class App extends React.Component {
constructor(props) {
super(props);
// Create a portal node: the link between the two ends of the portal
this.modalNode = portals.createPortalNode();
}
render() {
// Place an OutPortal somewhere: this is where the content will appear.
// Could be many levels deep in your app - you just need to get the modalNode
// there. For complex cases you might want to put it in a context to distribute it.
return <div>
<Child modalNode={this.modalNode} />
<portals.OutPortal node={this.modalNode} />
</div>;
}
}
const Child = props => {
// Place an InPortal somewhere: this is where the content is defined
return <portals.InPortal node={props.modalNode}>
<Modal>
<div>Modal :-)</div>
</Modal>
</portals.InPortal>
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
In the above: Child defines some modal content it wants to appear, and App defines the space where modal content should appear. You can use this to link parts of your app, and send rendered content between them. Hope that helps!
I have a react component called "header" which is going to be the header element on my webpage. Currently, all I have for the header component is:
import React from 'react';
import '../header/header.scss';
export default class Header extends React.Component {
render() {
return <div className="alignment">Test</div>
}
}
and my stylesheet is also simple:
.alignment{
text-align: center;
}
I placed the header component on my main App.js page, but the text alignment isn't showing up. I used Chrome debugger tools, and it is not even showing up in the styling as a class. I'm not sure what else to do, maybe I'm missing an import somewhere?
I'm building a React app that has links pointing to predefined routes.
Click Here
The routes resolve fine, but it's refreshing the page, thereby slowing down app performance. How do I avoid re-rendering the entire page?
Fix the problem by using the <Link> tag included with react-router.
import React from "react";
import { Link } from 'react-router-dom';
export class ToolTip extends React.Component {
render() {
return (
<Link to="/My/Route">Click Here</Link>
)
}
};
First answer was correct but I didn't found Link from react-router-dom. It was in my case here:
import { Link } from 'react-router';
You need to:
import { Link } from "react-router-dom"
then import the component you wish to go to
import Example from "./component/Example"
Then use Link like this
<Link to="/Example">
<h4>Example Page</h4>
</Link>
This will stop the refreshing.
Note that, if to="/Example" matches a route you've specified in your BrowserRouter and then it sends you there.
Learn more here Reat Training / React Router
Hi semantic ui react example
<Menu.Item name="NotFound" as={NavLink} to="/dadsadsa" />
In case the above methods don't work, check if you are importing the right component where you are defining the routes. (In my case, I imported a component with the same name but from a wrong path)