There are several way to style a component. It's quite a challenge to encapsulate style for a component but also allow customization.
You can style your components using the classic class
attribute. In React, it's translated to the className
property.
<div className="a-class">...</div>
You can use multiple classes
<div className="a-class another-class">...</div>
You can use some tricks to add classes conditionaly
<div className={[condition1 ? 'a-class' : '', !condition1 ? 'another-class' : ''].join(' ')}>...</div>
Using webpack, it's pretty easy to inject CSS parts inside a javascript file
.MyComponent-root-style {
color: red;
background-color: blue;
}
import React, { Component } from 'react';
import './MyComponent.css'; // inject css (using webpack)
export class MyComponent extends Component {
render() {
return (
<div className="MyComponent-root-style">...</div>
);
}
}
React let you write inline style pretty easily
import React, { Component } from 'react';
const Styles = {
myComponent: {
color: 'red',
backgroundColor: 'blue',
height: 42 // implicit conversion to '42px',
width: '100%'
},
...
};
export class MyComponent extends Component {
render() {
return (
<div style={Styles.myComponent}>...</div>
);
}
}
if you want to display component conditionaly, you can use truthy/falsy trick
export class MyComponent extends Component {
render() {
return (
<div>
{this.state.loading && (
<h2>Loading ...</h2>
)}
{!this.state.loading && (
<h2>Loaded</h2>
)}
</div>
);
}
}
sometimes you want to write a component that will render its children, but you'd like to add some props to the children.
It's quite useful with react-router
for instance. To do that your can use React.cloneElement
import React, { Component } from 'react';
export class MyComponent extends Component {
render() {
return (
<div>
<h2>{this.props.title}</h2>
{this.props.children && React.cloneElement(this.props.children, {
newProps: 'new prop value'
})}
</div>
);
}
}
If you want to fetch some data when a component is mounted to the dom, use the lifecycle function componentDidMount
export class MyComponent extends Component {
state = {
location: null
};
componentDidMount() {
// it's always a good thing to load data when the component is already monted into the DOM
// event if it's not http related
fetch('https://freegeoip.net/json/')
.then(r => r.json())
.then(location => this.setState({ location }));
}
render() {
return (
<div>
{!this.state.location && (
<h2>Loading ...</h2>
)}
{this.state.location && (
<pre>{JSON.stringify(this.state.location, null, 2)}</pre>
)}
</div>
);
}
})
import React, { Component } from 'react';
export class MyComponent extends Component {
state = {
content: ''
};
onChange = (e) => {
this.setState({ content: e.target.value });
};
sendContent = () => {
const content = this.state.content;
this.setState({ content: '' }, () => {
// do whatever you want with content
});
};
render() {
return (
<div>
<input type="text" value={this.state.content} onChange={this.onChange} />
<button type="button" onClick={this.sendContent}>Send content</button>
</div>
);
}
}