How can I avoid inline styles with React? - css

The code written below works correctly, but I was told to re-do the code in order to avoid inline styles.
export default class ProductDetail extends Component {
makeStyle(name, value) {
return {
backgroundColor: name === 'Color' ? value : "#1D1F22",
}
}
render() {
return (
<div className='sizesWrapper'>
{size.items.map(item => (
<div
key={item.value}
style={this.makeStyle(size.name, item.value)}
className="productSize"
>
{size.name !== 'Color' && item.value}
</div>
))}
</div>
)
}
}
how can I use CSS to change the backgroud-color of each iteration of item in items array instead of using:
style={this.makeStyle(size.name, item.value)}

You can create a CSS file and import it in your JS file. It will apply the CSS to your component

Related

How can I dynamically set style of a mapped element without using inline styling?

I'm coding a React function with parent component containing an array of objects:
let const ingredients = [
{name:"lettuce",color:"green"},
{name:"tomato",color:"red"}
]
...
In a child component, there is a map function that breaks down an array to single items to be displayed in a div.
What is the best practice for defining CSS styling for an object className:"name" to set backgroundColor: {ingredient.color};? I'm trying to avoid manual entry of the entire set of key/values of 'ingredients', to allow updating the object without breaking the code.
I'm currently using inline styling, which I have been advised against. Currently using:
let burg = props.toppings.map((item) => {
const divColor = {backgroundColor: item.color};
return (<div style={divColor}>{item.name}</div>)
Inline style is bad when you have other solution to do what you want. Here, you have a string that is the color (red, green, etc.) so you could write a css class for every color, but that is of course a really bad idea. Inline style is the good way to do it here.
I would suggest setting the class of the div instead of the style. That way you can change the look without resorting to inlining the style.
You could create a css class for lettuce with the background color green, instead of using the item.color you'd set class={ item.name }
You can use this way.
css can be more handy if you use scss
// css
.color-green {
color: green;
}
.color-red {
color: red;
}
import React from "react";
import "./styles.css";
const ingredients = [
{ name: "lettuce", color: "green" },
{ name: "tomato", color: "red" }
];
const Vegetable = ({ color, text }) => {
return (
<p>
this is <span className={`color-${color}`}>{text}</span> color{" "}
</p>
);
};
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
{ingredients.map((item, index) => {
return <Vegetable key={index} color={item.color} text={item.name} />;
})}
</div>
);
}

Add CSS for html selector based on React state?

I'd like to set overflow-y: hidden for the html selector (not an element) based on whether a React class component state variable is true. Is that possible?
If you mean you want to apply the overflow-y to the actual HTML tag then putting this code in the render worked for me
...
render() {
let html = document.querySelector('html');
this.state.test === "test" ? html.style.overflowY = "hidden" : html.style.overflowY = "visible";
return (
....
)
};
You can do
function MyComponent() {
// Set your state somehow
const [something, setSomething] = useState(initialState)
// Use it in your className`
return <div className={!!something && 'class-name'} />
}
If you have multiple class names to work with, a popular package is (aptly named) classnames. You might use it like so:
import cx from 'classnames'
function MyComponent() {
const [something, setSomething] = useState(initialState)
return <div className={cx({
'some-class' : something // if this is truthy, 'some-class' gets applie
})} />
}
Yes, It's possible. You can do this.
function App() {
const [visible, setVisible] = useState(false);
useEffect(() => {
const htmlSelector = document.querySelector("html");
htmlSelector.style.overflowY = visible ? "unset" : "hidden";
}, [visible]);
return (
<button onClick={() => setVisible(prevState => !prevState)}>
Toggle overflow
</button>
);
}
See the full example on CodeSandbox
You can use the style property to set inline CSS:
<div style={{ overflowY: hide ? 'hidden' : 'auto' }}>

Gutenberg add style attribute using block filter

I'm trying to add a style attribute in the block editor to a block's wrapper using a block filter:
const addStyle = createHigherOrderComponent( ( BlockListBlock ) => {
return ( props ) => {
return <BlockListBlock { ...props } className="my-class" style="color: red" />;
};
}, 'addStyle' );
wp.hooks.addFilter( 'editor.BlockListBlock', 'my-plugin/add-style', addStyle );
Only the my-class class name is added to the class attribute but no style attribute. Is it possible to add a style attribute as well? The documentation states:
It receives the original BlockListBlock component and returns a new
wrapped component.
but does not say you can add only class names.
For the rendering part it's:
wp.hooks.addFilter('blocks.getSaveContent.extraProps','my-plugin/add-style', function(props, name, atts){
return Object.assign(props, { 'style': 'color: red' });
});
Couldn't figure it out for the edit function tho.

Is there a function to that creates a custom block inside my gutenberg block?

I'm making a slider block and I want to create a slide block for each image I choose.
I already have a fully functioning slide block.
The question is, how can I create call the slide block from the slider block? I think there must be a way through the API and I found the function createBlock() but nothing is really working
const { createBlock } = wp.blocks;
//
// some code
//
<div id={ listId } className={ classes } key={ index }>
{createBlock('illmatic6514/slide')}
</div>
I'm expecting a slide block to be created. (To make it simple I removed variables from the slide block and put in a static image)
I'm getting "Cannot read property 'attributes' of undefined"
Even if I call createBlock('core/paragraph') I get "Objects are not valid as a React child"
You probably want to define Slide as a component instead of a block:
function Slide(props) {
return <div>{props.slideName}</div>;
}
Or as a class that extends Component:
const { Component } = wp.element
class Slide extends Component {
render() {
return (
<div>{ this.props.slideName }</div>
)
}
}
And then in your Slider block you would use that component:
edit(props) {
return (
<div>
<Slide slideName="Slide 1" />
<Slide slideName="Slide 2" />
</div>
)
}
https://reactjs.org/docs/components-and-props.html

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