Search code examples
javascriptcssreactjssasscss-variables

Changing colours using custom CSS properties - resetting on refresh? (ReactJS)


I am trying to allow my admins to be able to change the branding and colours of my project, I am currently using CSS custom properties to do this, however, this doesn't seem to be saving. When I refresh the page it is refreshing the colours back to it's original state. Is there a way I can fix this?

CODE

JavaScript - Admin panel


import React, { Component } from 'react'
import './CompanyBranding.scss'
import firebase from 'firebase'

export default class CompanyBranding extends Component {

    state = {
        content: [],
        textbox: "",
        link: "",
        primaryColour: "",
        secondaryColour: ""
    }

    componentDidMount() {
        firebase.firestore().collection('site').doc('public').collection('footer').doc('content').get().then(doc => {
            const content = []
            const data = doc.data()
            this.setState(data)
            content.push(data)
            this.setState({content})
            this.setState({contentLength: content.length})
          })
    }

    handleChange = (e) => {
        this.setState({
            [e.target.id]: e.target.value,
        }) 
    }

    
    handleSubmit = (e) => {
        e.preventDefault();
        firebase.firestore().collection('site').doc('public').collection('footer').doc('content').set({
            textbox: this.state.textbox,
            link: this.state.link
        }).then(alert("Updated"), 
        document.getElementById("companydetails").reset()
        )

        document.documentElement.style.setProperty(
            '--primary-color', 
            this.state.primaryColour
        )

        document.documentElement.style.setProperty(
            '--secondary-color', 
            this.state.secondaryColour
        )
    }




    render() {
        return (
            <div>
                <div className="CompanyBranding">
                    <h1 className = "PageHeading"> Branding</h1>
                        <form className = "CompanyBrandingForm">
                            <label htmlFor = "Logo"> Company Logo</label> <br/>
                            <input type = "file" id = "Logo" name = "Logo" accept = "image/png, image/jpeg"/><br/><br/>

                            <label htmlFor = "PrimaryColour"> Primary Colour </label> <br/>
                            <input type = "color" id = "primaryColour" name = "PrimaryColour" onChange = {this.handleChange}/><br/><br/>

                            <label htmlFor = "SecondaryColour"> Secondary Colour </label> <br/>
                            <input type = "color" id = "secondaryColour" name = "SecondaryColour" onChange = {this.handleChange}/><br/><br/>

                            <button onClick = {this.handleSubmit} className = "SubmitButton"> Submit </button>
                        </form>
                </div>

                <div className="FooterContent">
                    <h1 className = "PageHeading"> Footer </h1>
                        <form className = "CompanyBrandingForm">

                            <label htmlFor = "textbox"> Text box</label> <br/>
                            <textarea id = "textbox" value = {this.state.textbox} onChange = {this.handleChange} />
                            <br/><br/>

                            <label htmlFor = "link"> GDPR link </label> <br/>
                            <input type = "text" id = "link" value = {this.state.link} onChange = {this.handleChange}/>


                            <button onClick = {this.handleSubmit} className = "SubmitButton"> Submit </button>
                        </form>
                </div>

            </div>
        )
    }
}

Variables.scss


:root {
    --primary-color: #2f78e6;
    --secondary-color:#2d4f81;
}

// Primary colour (can be changed by admin)
$base-colour: var(--primary-color);
$secondary-color: var(--secondary-color);

Solution

  • When you refresh the page your entire application is rerendered. So the color goes back to the default value as the state is lost. This means you need some kind of persistence.

    Depending on what you're trying to achieve there are a few options:

    If you want the admin to change the theme for everyone you should store that theme in some kind of database, for instance, Firestore as you are already using it. When you initialize the state, you run a query and fetch the value from Firestore.

    If you want the admin to change the theme only for himself, you can set the preferred color in the localStorage and then fetch the value from it when you initialize the state.