# Applying CSS styling based on different pages in React

Short Story: I created this website last year in plain HTML, CSS, JS which I can't even remember how I wrote that and now I can't even edit the website without breaking it. So, I'm re-writing everything in a proper way using React.

So, I'm making a website using React ( I'm still learning ) and I got confused about using CSS with it.

I have a TW component for type-writing animation like on the home and projects page.

You can see that same animation has different styles in home and projects page.

Previously, I have just used different CSS rules present in different webpages( with code redundant ). But doing same in React is not possible because of it's component approach.

Code:

typewriter.js

import React from 'react';
import { ICH } from '../individual-char-highlight/individual-char-highlight'; // When the mouse is hovered over a char it changes color
import s from './typewriter.css'; // Default style for this component

/**
* By default, it returns a component which produces typewriter animation on the array of strings passed as this.props.data
* *************************
* *************************
* Description of props:
*
* "Needed props"
* name: this.props.data[], type: Array(String)-> Produces typewriter animation on the array of strings passed
* *************************
* "Optional props"
* name: this.props.time, type: Integer, default: 60 -> Milliseconds to delete or add one character to the screen
*
* name: this.props.passTo, type: String, default: undefined -> Used to pass the data to specified component after final string is constructed before it is displayed.
*/
export class TW extends React.Component {

constructor(props) {
super(props);

// Initial state
this.state = {
data: ''
};

// - Mark methods
this.animate = this.animate.bind(this);
this.passTo = this.passTo.bind(this);
this.animate();

}

/**
* animate - Typing Animation logic
*
*/
animate() {

var dataIndex = 0; // It is used to iterate the this.props.data
var d = this.props.data[dataIndex]; // Current string to apply animation
var strLength = d.length; // Length of current string
var text = this.props.data; // It is the string that changes to produce type writer effect
var flag = true; // It is used to add or remove the character from text
var index = strLength; // It is used in substr to specify the to argument and from is always 0
var count = 0; // It is used to delay the adding of first character when text is empty.

setInterval(function () {

if (text.length == 0) // If the string text is empty
{
if(count == 15) // Initially 0 waits till it gets to 15 and then adds the char
{
dataIndex = (dataIndex >= this.props.data.length - 1) ? 0 : ++dataIndex;
d = this.props.data[dataIndex]; // Update the string to apply animation on
strLength = d.length; // Update the length of current string
index = 1; // Increment index to add the 1st char
flag = true; // Make it true so it adds chars one-by-one in next else if
count = 0; // Again make it 0 for next iteration

}
else
{
count++; // Increment count when text is empty untill count = 15
}

}
else if (strLength + 20 == index) // same like count, +20 delays the deletion after the text is full
{
index--; // Decrement index to delete the last char.
flag = false; // Make it false so it delets chars one-by-one in next else if
}
else if (flag) // It executes to add the chars to text one-by-one
{
index++;
}
else if (!flag)  // It executes to delete the chars from text one-by-one
{
index--;
}

text = d.substr(0, index) // Display the string, even if it's empty
this.updateState(text); // Call to update the this.state.data

}.bind(this), this.props.time); // Change this number to change the typing speed. Less = Fast
}

/**
* updateState - Updates the state with current text to call the render.
*
* @param  {String} text Displays the constructed text string
*
*/

this.setState({ // Display the constructed text string
data: text,
});
}

/**
* passTo - Sends the constructed string to another component for further components if specified any. Otherwise returns unmodified string as component
*
* @return {span}  Span which might be modified by other components or not
*/
passTo(){

let mainData;
// style is used to position the component at the center approximately due to cursor(which shifts to left)
// //style is used for cursor span to position the cursor according to the this.props.data
if(this.props.passTo == 'ICH'){
mainData = [
<span className={s['data']}  style={{position:'relative',left:'5%'}}><ICH data = {this.state.data} name="typewriter" /></span>,
<span className={b['blink'] + ' ' + s['cursor']} style={{position:'relative',left:'5%'}}>&#9614;</span>
]
}
else {
mainData = [
<span className={s['data']}>{this.state.data}</span>,
<span className={b['blink'] + ' ' + s['cursor']}>&#9614;</span>
]
}

return mainData;
}

render() {

let displayData = this.passTo(); // Final span to be displayed after all the modifications

return (
<span>{displayData}</span>
);
}
}

/**
* Default value of this.props.time is 60 milliseconds
* @type {Object}
*/
TW.defaultProps = {time: 60};

Now I want to apply a style based on the webpage where it is used.

I thought of two options.

1) As you can see above, I'm using passTo() and this.props.passTo to send the data to another component for further animation. Similarly, I can send a style object from parent component as props and use the same above logic to apply the style as in-line using conditional statements.

2) Doing similar to option 1 but instead of passing style object, adding the styles in typewriter.css(which has default styles for this component) with className as the webpage name and applying it.

Which one is better? And is there a way to apply CSS from parent component?

Thank you!