I have React parent component A which has its own scss file a-style.scss. Component B is child of A. A is passing styleInfo object as props which is applied on B.
My question is - is there any way we can define styleObj in a-style.scss instead of defining it inline. I want all styling related info should be in external scss file.
Component A
import "./a-style.scss";
import B from "./B.js";
class A extends Component {
constructor(props) {
super(props);
}
const styleObj = {
backgroundColor: "#F9F9F9",
borderRadius: '2px',
color: "#686868",
};
render() {
return (<B styleInfo={this.styleObj}></B>);
}
}
Component B
class B extends Component {
constructor(props) {
super(props);
}
render() {
return (<div style={this.props.styleInfo}></div>);
}
}
The standard way is to define CSS properties based on class in your scss/css. And then pass className from props in your React component:
class A extends Component {
theme = "themeA";
render() {
return (<B styleInfo={this.theme} />);
}
}
class B extends Component {
styleClass = ["B"];
render() {
const className = styleClass.push(this.props.styleInfo).join(' ');
return (<div className={className} />);
}
}
.themeA {
background-color: #F9F9F9;
border-radius: 2px;
color: #686868;
}
.B {
/* Some style for B component */
}
Why not just import that one file directly into B.js?
Is there any benefit of having it go through a parent, seems like necessary routing to me!
If you do need this, then I would just keep it in JS, as this is what JS is good at, or at least, have JS just do the className switching and, again, just have one css file that is a main style lookup hash!
Best of luck!
Related
I have a trivial LitElement class that I want to style with some internal CSS:
import {LitElement, html, css, customElement, property} from 'lit-element';
#customElement('address-card')
export class AddressCard extends LitElement {
#property()
streetAddress?: string;
#property()
postalCode?: string;
#property()
city?: string;
static get styles() {
return css`
.address { border: 1px dashed gray; }
`;
}
render() {
return html`
<div class="address">
<div>${this.streetAddress}</div>
<div>${this.postalCode} ${this.city}</div>
</div>
`;
// Remove this method to render the contents of this view inside Shadow DOM
createRenderRoot() {
return this;
}
}
The static get styles() method should allow me to add styles to the component, but nothing I add there seems to get applied. Not even a * { ... } selector, which should affect all elements, seems to do anything.
The problem is the createRenderRoot() method. If you disable shadow root, there's no need to encapsulate styles inside the component implementation - you can use global CSS. If you want to encapsulate styles, remove the createRenderRoot override and the static get styles() rules will get applied.
im trying to create a new lit element component extending from other component
but render method donĀ“t works.
the component is empty..
export default class ChildComponent extends FatherComponent {
static get styles() {
return css`
:host {
display: block;
}`;
}
render() {
return html`<h1>Hi</h1>`;
}
}
window.customElements.define('child-component', ChildComponent);
I had the same kind of issue today. It seems that render() was not triggered.
To solve my issue I had to call super.connectedCallback() in the connectedCallback() methods for both child and parent.
I also call super() in the constructor.
Hope that helps.
I have a child component needs to use spectre.css, but when I import spectre.css in child component, parent component also got affected. How can I make spectre.css only apply to the child component? Thanks
Parent Component:
class ParentComponent extends React.Component{
render(){
return <ChildComponent></ChildComponent>
}
}
In Child component,
import from 'spectre.css'
class ChildComponent extends React.Component{
/* ... */
}
most probably your css is bundled in one single file.
You can add className to your components, to differentiate them.
you can create your styles inside your component
const styles= {
wrapper: {
color: red,
},
};
class ChildComponent extends React.Component{
/* ... */
render() {
return (<div style={styles.wrapper}> </div>
}
}
or you can try css-in-js libraries such as emotion or styled-components
I have a react component where I am trying to change the background color of the css when clicking the div.
I know you can set the color in the component, but I am using this component many times, and don't to make multiple component files with just a different color, and even if I did, I am curious besides the fact.
How can I access (or even console.log to figure it out on my own) the css file and its properties through the component? Thanks ahead of time.
If you want to keep all background-color styles in your .css/.scss file, you will need to have a good className strategy to link the styles to your components. Here is my suggestion:
styles.scss
.blue {
background-color: blue;
&.clicked {
background-color: red;
}
}
Container.js
import React from 'react';
import ClickableDiv from './ClickableDiv.js';
const Container = () => (
<ClickableDiv className="blue">
<p>This is my text.</p>
</ClickableDiv>
);
export default Container;
ClickableDiv.js
import React, { Component } from 'react';
class ClickableDiv extends Component {
constructor() {
super();
this.state = { clicked: false };
this.handleDivClick = this.handleDivClick.bind(this);
}
handleDivClick() {
this.setState({ clicked: true });
}
render() {
const divClassName = [this.props.classname];
if (this.state.clicked) divClassName.push('clicked');
return (
<div className={divClassName.join(' ').trim()} onClick={this.handleDivClick}>
{this.props.children}
</div>
);
}
}
export default ClickableDiv;
Rendered Markup
Unclicked:
<div class="blue"><p>This is my text.</p></div>
Clicked:
<div class="blue clicked"><p>This is my text.</p></div>
You can pass in the desired background color as a prop, and use internal state with an onClick handler.
Container.js
import React from 'react';
import ClickableDiv from './ClickableDiv';
const Container = () => (
<ClickableDiv backgroundColor="#FF0000">
<p>This is my text.</p>
</ClickableDiv>
);
export default Container;
ClickableDiv.js
import React, { Component } from 'react';
class ClickableDiv extends Component {
constructor() {
super();
this.state = {};
this.handleDivClick = this.handleDivClick.bind(this);
}
handleDivClick() {
const { backgroundColor } = this.props;
if (backgroundColor) this.setState({ backgroundColor });
}
render() {
const { backgroundColor } = this.state;
return (
<div style={{ backgroundColor }} onClick={this.handleDivClick}>
{this.props.children}
</div>
);
}
}
export default ClickableDiv;
Better to make an external css file and write your css code in that file and just import that one in index.html
I found the child component Element was not connected when I want to use action in child component.
how to connect it ?
code:
import { connect } from 'react-redux';
import * as actions from '../actions';
class Element extends React.Component {
constructor(props) {
super(props);
}
render() {
let { children } = props.el.children;
return (
<div>
{ children ?
children.map(el =>
<Element key={ 'el-' + el.id } el={ el } />
)
:
null
}
</div>
)
}
}
Element = connect(
null
,
actions
)(Element);
export default Element;
You are rendering <Elemnt /> inside it's own render function.
If you just want to pass the children down the render function of your Element component then just change it to this:
import { connect } from 'react-redux';
import * as actions from '../actions';
class Element extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
{ this.props.children }
</div>
)
}
}
Element = connect(
null
,
actions
)(Element);
export default Element;
Note that the wrapper <div> is there because current version of react only allow one top level element in the render body, and this.props.children can hold more than one element.