1

I have a component that determines the location of the desired .css file via an ajax call in componentDidMount(), that I want to then load before render. I've tried just adding a <link> element in the render return (didnt work), I've also tried directly injecting the tag into the head using vanilla JS, but this also didnt work:

async componentDidMount() {
    await this.fetchPanelInfo().then(result => {
        console.log(this.state);

        const link = document.createElement("link");
        link.href= this.state.stylePath;
        link.rel = "stylesheet";
        link.type="text/css";
        document.head.appendChild(link);
        //const style = document.getElementById("style-direction");
        //style.href = this.state.stylePath;
    })
}

The shortened component:

class Panel extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        token: "f0be0f7d231305a832fd1eef4bcb0e9ba18f2d65",
        error: null,
        errmsg: null,

        menuContent: null,
        stylePath: null,
        services: null,

        loading: true
    }
    isLoggedIn().then(logged => {
        //Nothing for now
    })
}
//Gets all information about the panel
async fetchPanelInfo() {
    await axios({
        method: 'post',
        url: `${ENDPOINT}`,
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        },
        data: this.state
    }).then(result => {
        console.log(result.data);
        this.setState({
            error: result.data.error,
            menuContent: result.data.menu,
            stylePath: result.data.stylePath,
            services: result.data.services,
            loading: false
        });
    }).catch(err => {
        console.log("error");
        console.log(err);
        this.setState({error: err.error})
    });
}

async componentDidMount() {
    await this.fetchPanelInfo().then(result => {
        console.log(this.state);

        const link = document.createElement("link");
        link.href= this.state.stylePath;
        link.rel = "stylesheet";
        link.type="text/css";
        document.head.appendChild(link);
        //const style = document.getElementById("style-direction");
        //style.href = this.state.stylePath;
    })
}

render() {
    if(this.state.loading) return null;
    return (
        <section className="panel">

            <p>Hello</p>
            <Menu items={this.state.menuContent} />
        </section>
    );
}
}

This is a page that <Router> navigates to, so I cant explicitly pre-fetch the name of the stylesheet and import separately, because the stylesheet loaded depends on the supplied token (i.e., it varies from token to token).

Any ideas?

4
  • Can you be more specific in what didn't work? e.g. for componentDidMount method, whether link tag didn't append in head or css didn't load from url or css loaded but it didn't apply to page? didn't work is too vast in this context. Commented Jan 13, 2020 at 15:42
  • @Sunil in both cases, the <link> tag appeared (either in the body, or when I injected it directly to the head, in the head), just did nothing. I also double checked in the network tab and both instances the files loaded fine; just did not apply the style to the page. Commented Jan 13, 2020 at 16:35
  • 1
    Glad you made it work using require. But the link tag approach in componentDidMount should also work. I just tried it in jsfiddle and it works fine. Commented Jan 13, 2020 at 16:51
  • @Sunil hm, interesting - it may have something to do with the rest of the structure, unfortunately I really cant say as im fairly new to React. great to see regardless though, means I surely wasnt far off! Commented Jan 13, 2020 at 17:13

1 Answer 1

1

I managed to load and apply the dynamic .css file, as follows:

async componentDidMount() {
    await this.fetchPanelInfo().then(result => {
        console.log(this.state);

        if(this.state.stylePath === undefined) {
            require("../" + "core/data/default/styles.css");
        } else {
            require("../" + this.state.stylePath);
        }
        const React = require('react');
    })
}

Basically using the require() module.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.