React component not rendering inline CSS - css

I am trying to write a react application where the App component renders an array of components to the screen. But the inline CSS are not showing up.
//App component
import data from "./data.js"
import Item from "./Item"
export default function App(){
const cardElements = data.map(item => <Item/>)
return (<div className='app'>
{cardElements}
</div>);
}
//Item component
export default function Item(){
const customStyle = {border: "2px solid black"};
return (<div style={customStyle} >Item component</div>);
}
The inline CSS in the Item component does not reflect on the webpage.

As you can see in the snippet below the inline style does indeed work. What is likely happening here is your style is bering overridden but we'd need more information to know for sure.
Sidenote: don't forget to add key prop when using .map in React.
const data = [1, 2, 3, 4];
function App() {
const cardElements = data.map(item => <Item key={item} />)
return (
<div className='app'>
{cardElements}
</div>
);
}
function Item() {
const customStyle = { border: "2px solid black" };
return <div style={customStyle}>Item component</div>;
}
ReactDOM.createRoot(
document.getElementById("root")
).render(
<App />
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>

Related

Changing body background image with React

So, I'm trying to create a React App that changes the background image of the body. I did this by giving the body in my index.html an id of "body." I can get this to work with changing the background COLOR just fine. When I try to reassign the background IMAGE, though, I can't seem to get it to work no matter what I try.
This works:
document.getElementById("body").style.backgroundColor = "blue";
This doesn't:
import explosion from "./explosion.png";
function Boom(){
document.getElementById("body").style.backgroundImage = "url('" + {explosion} +
"')";
Why? I've tried writing this many different ways.
this worked for me :
import { useEffect } from "react";
import img from './img.png';
export default function App(){
useEffect(()=>{
document.getElementById('body').style.backgroundImage = `url('${img}')`;
})
return <>
<div id="body"
style={{height:'300px'}}
>
</div>
</>
}
or you can use inline css style :
import img from './img.png';
export default function App(){
return <>
<div id="body"
style={{
height:'300px',
backgroundImage: `url('${img}')`,
}}
>
</div>
</>
}
you need to pass the URL of the image as a string, without wrapping it in curly braces {}
You can try this code
import { useEffect } from "react";
export default function App() {
const bgUrl =
"https://images.unsplash.com/photo-1605106250963-ffda6d2a4b32?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=880&q=80";
/*useEffect Hook allows you to perform side effects in your components. Such as fetching data, directly updating the DOM, and timers*/
useEffect(() => {
Boom();
}, []);
const Boom = () => {
document.getElementById("body").style.backgroundImage = `url(${bgUrl})`;
};
return (
<div className="App">
<h1>Hello World!</h1>
</div>
);
}
here's a link to the working demo Change Background Image

Why inline CSS is not working on component in react?

I'm using a component in react.
import style from "../../Style/Styles.module.scss";
const Anchor = (props) => {
return <a className={style["anchorTags"]} href={props.href}>{props.title}</a>;
};
export default Anchor;
where I have already written CSS for this component in my SCSS file.
.anchorTags {
border: 2px solid $Very-Light-Gray;
color: $Very-Light-Gray;
}
but when I'm writing inline css in a component when using this on another component it is not working.
import style from "../../Style/Styles.module.scss";
import Anchor from "./achortag";
<Anchor
style={{ paddingBlock: "0.7em", paddingInline: "2em" }}
href="/viewPlan"
title="VIEW PLANS"
/>
Please share your suggestion on how this will work?
In Anchor component:
const Anchor = (props) => {
return (
<a className={style.anchorTags} href="#" style={props.style}>
{props.title}
</a>
);
};
export default Anchor;
or use the spread operator, this will add any additional attributes:
const Anchor = (props) => {
return (
<a className={style.anchorTags} href="#" {...props}>
{props.title}
</a>
);
};
export default Anchor;
To use the desired style, you must use this syntax:
import style from "../../Style/Styles.module.scss";
const Anchor = (props) => (
<a className={style.anchorTags} href={props.href} {...props}>{props.title}</a>;
);
export default Anchor;
For more information, you can read this (Adding a CSS Modules Stylesheet).

react-moveable and css modules - cant apply css styling

I'm using react-moveable to have drag and drop support for some component. I'm trying to make the control box disappear until the user clicks on the target.
So first, I want to apply some CSS to the control box, but I can't seem to do it. The docs specify that a className could be set, but it doesn't work for me for some reason.
The component looks something like this:
import React from "react";
import Moveable from "react-moveable";
import { makeMoveable, DraggableProps, ResizableProps, RotatableProps, Rotatable, Draggable, Resizable } from "react-moveable";
import MoveableHelper from "moveable-helper";
import styles from './label.module.css';
const Label = () => {
const [helper] = React.useState(() => {
return new MoveableHelper();
})
const targetRef = React.useRef<HTMLDivElement>(null);
return (
<div className="container">
<div>
name
</div>
<Moveable
className={styles.moveable1}
target={targetRef}
draggable={true}
resizable={true}
rotatable={true}
origin={false}
onDragStart={helper.onDragStart}
onDrag={helper.onDrag}
onResizeStart={helper.onResizeStart}
onResize={helper.onResize}
onRotateStart={helper.onRotateStart}
onRotate={helper.onRotate}
/>
</div>
);
};
export default Label;
And the css module file label.module.css:
.moveable1 .moveable-line .moveable-direction {
background: red !important;
}
I tried to set the className as string, play around with the class names in the css files and more, but nothing changes the control box style.
Any ideas?
The control box is defined by the zoom and the renderDirection
We can make it disappear (zoom default is 1 )
zoom={0}
and modify / hide the border controls. (Default)
renderDirections={["nw", "n", "ne", "w", "e", "sw", "s", "se"]} )
And then you can apply some styles to the target div with a normal onClick function and useState hook.
import React from "react";
import Moveable from "react-moveable";
import { makeMoveable, DraggableProps, ResizableProps, RotatableProps, Rotatable, Draggable, Resizable } from "react-moveable";
import MoveableHelper from "moveable-helper";
import styles from './label.module.css';
const Label = () => {
const [helper] = React.useState(() => {
return new MoveableHelper();
})
const targetRef = React.useRef<HTMLDivElement>(null);
const [styles, setStyles] = useState( {border: "1px solid green";} )
const handleStyles = e => {
// Your styles...
// Your setState Hook
setStyles({border: "1px solid blue"})
}
return (
<div className="container">
<div onclick={handleStyles} style={styles}>
name
</div>
<Moveable
className={styles.moveable1}
target={targetRef}
draggable={true}
resizable={true}
rotatable={true}
origin={false}
onDragStart={helper.onDragStart}
onDrag={helper.onDrag}
onResizeStart={helper.onResizeStart}
onResize={helper.onResize}
onRotateStart={helper.onRotateStart}
onRotate={helper.onRotate}
{ /** Hide the control box * / }
zoom={0}
renderDirections{["nw", "n", "ne"]}
/>
</div>
);
};
export default Label;
Docs:
Zoom Types:
https://daybrush.com/moveable/release/latest/doc/Moveable.html#zoom
Render Directions: https://daybrush.com/moveable/release/latest/doc/Moveable.html#.RenderDirections
CSS style Box:
https://github.com/daybrush/moveable/blob/master/handbook/handbook.md#toc-directions
👀 style={{ background: 'yellow' }}
Hope you find this useful.
Regards,
M.
💀
Just to be sure, did you try .moveable-control css class name as in:
.moveable-control {
background: red !important;
}

Testing Style on React component

I have the following class with a function, that opens a modal (open_modal(...)) in a separate file to a component as I have a large number of modals that use this functionality.
import open from "open";
import $ from "jquery";
class ReactHelpers {
static open_webpage(page_url) {
open(page_url);
}
static open_modal(overlay_id, modal_id) {
$(overlay_id).css("display", "block");
$(modal_id).css("display", "block");
}
static close_modal(overlay_id, modal_id) {
$(overlay_id).css("display", "none");
$(modal_id).css("display", "none");
}
}
export default ReactHelpers;
I am trying to assert that the open_modal function has added css to the divs in question as below:
it('should close the modal', function () {
const wrapper = shallow(
<div id="overlay_id">
<div id="modal_id">
<p>modal</p>
</div>
</div>
)
const overlay = wrapper.find('#overlay_id')
const modal = wrapper.find('#modal_id')
ReactHelpers.open_modal(overlay, modal);
console.log('OVERLAY ', overlay);
expect(overlay.prop('style')).toHaveProperty('display', 'block');
expect(modal_style).toHaveProperty('display', 'block');
});
Further, I'm sure to how the open_webpage function would be tested as this is a library function. In my other tests in my other components, I'm mocking this so it's never actually been tested.
Any help is greatly appreciated.
Thanks
To test style of dom elements:
You should mount the component (using mount), instead of just creating it (using shallow).
Since you're changing the style of dom element directly, You should test the style of the dom element (component.getDOMNode().style.display), instead of testing the react style property (component.prop.style).
example:
import $ from "jquery";
it("should create a div and changes its color to red", () => {
const wrap = mount(
<div id="red_el"></div>
);
const el = wrap.find("#red_el").getDOMNode()
$(el).css("color", "red");
expect(el.style.color).toEqual("red");
});
In your case:
it("should open modal", () => {
const wrapper = mount(
<div>
<div id="overlay" style={{ display: "none" }}>
<div id="modal" style={{ display: "none" }}>
overlay
</div>
</div>
</div>
);
const overlay = wrapper.find("#overlay").getDOMNode();
const modal = wrapper.find("#modal").getDOMNode();
ReactHelpers.open_modal(overlay, modal);
expect(overlay.style.display).toEqual("block");
expect(modal.style.display).toEqual("block");
});
See it live on codesandbox (switch to the tests tab to run the tests .)

using className in react

So what's the best pratice for using className in react. In specific multiple class names. I'm reading through the documentation and I don't really get a clear answer. I've seen things like:
const divStyle = {
color: 'blue',
backgroundImage: 'url(' + imgUrl + ')',
};
function HelloWorldComponent() {
return <div style={divStyle}>Hello World!</div>;
}
but is there a way for me to do something like this?
import React from 'react';
import ReactDOM from 'react-dom';
import './css/landing.css';
import './css/w3.css';
class Home extends React.Component {
const homeClasses = 'bgimg-1 w3-display-container w3-opacity-min';
render() {
return (
<div className={homeClasses}>
<h1>SUP</h1>
</div>
);
}
}
ReactDOM.render(
<Home />,
document.getElementById('root')
);
or even just list then out in the class name section?
It depends what your component should/will do.
If your component is fairly static you will want to use a built in style like your first example:
const mystyle = {
width: '100%',
...
}
<div style={mystyle}>...</div>
However, there are better ways that allow your component to be more dynamic for re-use, for instance using a class method to generate the style from props passed to it, like in this render function:
render() {
// User's preference or Default Style:
const defaultStyle = {
width: this.props.style.width || '100%',
height: this.props.style.height || '100%',
}
//if this.props.className doesn't exist use mycssclass
const defaultClassName = this.props.className || 'mycssclass'
return (
<div className={defaultClassName} style={defaultStyle}>...</div> )
Following this logic you can use the ternary operator to change the css class name based on props. A common solution is use an isActive state property and use it to determine which class should be used.
render() {
const activeClassName = this.props.className + ' mycomponent-active'
return (
<div className={this.props.isActive ? activeClassName : this.props.className} style={ this.props.style }
</div>);
}
Another common, but complex way to set your component's style is to use a function that will return a given style object, and use it like the first example.
Ultimately, you should decided whether you would like your component to be styled by the designer/user or should look the same no matter where it is used... if it is styled by the designer, just expose the CSS class name from props to the component or define a default:
<div className={this.props.className || 'someclassName'}>...</div>
otherwise, use an example above.
Yes, you can do this! Take a look at the snippet below:
class Example extends React.Component {
cssClasses = 'demo demo2';
render() {
return (
<div className = { this.cssClasses }>
Hello World
</div>
);
}
}
ReactDOM.render( <Example/> , document.getElementById('app'));
.demo {
color: blue
}
.demo2 {
font-size: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'></div>
Your error was the definition of the homeClasses. You can't declare it like
const homeClasses = '...';
Because, on the way that you did, homeClasses is a property of your component. You should not use const. Just:
homeClasses = '...';
And you forgot to use the this reference, because the homeClasses is an attribute of your component.
<div className={this.homeClasses}>
<h1>SUP</h1>
</div>
Exists and one away for this problem. You can use and read this data from file (example data.json) where can use this data like props of that.

Resources