1

Overview

In my custom Docusaurus page, a simple button event handler does not execute upon click. The file is in the form of a React component, as is the norm for Docusaurus pages.

What I did

1) I set up my Docusaurus application using docusaurus-init, as advertised on Docusaurus' GitHub page (see https://www.npmjs.com/package/docusaurus-init)

2) I added a custom page as described here https://docusaurus.io/docs/en/custom-pages. I.e., I added a JS file to the pages/ folder.

The custom page code

This is the entirety of the code for the page. The code within the React component is copied from a React example found in the docs. I added the console.log statements in the handlers.

const React = require('react');

const CompLibrary = require('../../core/CompLibrary.js');

class SignUp extends React.Component {
    constructor(props) {
        super(props);
        this.state = {value: ''};

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        console.log("Change occurred!");
        this.setState({value: event.target.value});
    }

    handleSubmit(event) {
        console.log("Submit occurred!");
        alert('A name was submitted: ' + this.state.value);
        event.preventDefault();
    }

    render() {
        return (
            <form onSubmit={this.handleSubmit}>
            <label>
            Name:
            <input type="text" value={this.state.value} onChange={this.handleChange} />
            </label>
             <input type="submit" value="Submit" />
            </form>
    );
    }
}

module.exports = SignUp;

Output I expect

An alert should pop up, and output should appear in the console. Because of event.preventDefault(), page should not be refreshed.

What happens

The input field as well as the button shows up just fine. I type some text in the input field and hit submit. Input field goes blank, no alert, no output in console (neither in client or on server). It appears a refresh took place, which event.preventDefault() apparently did not prevent.

Yangshun Tay
  • 49,270
  • 33
  • 114
  • 141
fralla
  • 457
  • 1
  • 4
  • 12
  • i had the same issue. I could solve it do delete the alert! Maybe also event.preventDefault() at the beginning maybe solved this problem. But I didn't proof it. – lewa9 Aug 08 '19 at 21:17
  • When you say "event.preventDefault() at the beginning maybe solved this problem", where exactly does "at the beginning " refer to? @lewa9 – fralla Aug 08 '19 at 21:27
  • I made an Answer! Please check it! – lewa9 Aug 08 '19 at 21:28
  • Appears there is no way to make it happen. See https://github.com/facebook/docusaurus/issues/1751. However, if someone knows a hacky way of doing it, please let me know! – fralla Aug 08 '19 at 21:49

2 Answers2

2

Hi Docusaurus maintainer here.

This is not a bug. In v1, React is used as a rendering engine, and the output of the build step is just HTML. There's no React runtime shipped to clients, hence event handlers would not work.

You will need to write script tags in your React component to get this to work. This is an example.

You should try Docusaurus 2 if you need to build rich websites. Your code will work as intended there.

Yangshun Tay
  • 49,270
  • 33
  • 114
  • 141
  • Ok, so you're saying it is possible to achieve the functionality of an event handler through script tags? Now, can you give some more detail on how the content of the script tag must be formatted? Clearly, it's not going to work the same way as in a plain HTML file. In the example you provided, e.g., it looks something like `{ this.props... && ( – fralla Aug 09 '19 at 01:34
  • You have to add ` – Yangshun Tay Aug 09 '19 at 05:06
  • 1
    Yeah, it works. Thanks. Are there any security concerns or other drawbacks doing it this way ("dangerouslySetInnerHTML" doesn't sound too encouraging), besides the code looking absolutely heinous? :p – fralla Aug 09 '19 at 19:32
  • It's hard to answer that question. But since Docusaurus produces a static content, the risk is smaller. Typically the risk comes from server-side rendering of malicious dynamic user input that gets executed in the browser. In the case of Docusaurus, typically all content is static and you are in full control of what you render, so the risk is very small. – Yangshun Tay Aug 09 '19 at 23:09
0

I checked it again. Try maybe this!

 <form onSubmit={this.handleSubmit.bind(this)}>

You forgot the binding to the react component. This maybe caused an error and it didn't come to event.preventDefault() statement

lewa9
  • 41
  • 6
  • also change it by all your inputs – lewa9 Aug 08 '19 at 21:32
  • Actually I tested nearly the same code like you, but no strange behavior appears! It worked! Also your binding was correct by your side. – lewa9 Aug 08 '19 at 21:43
  • Really... that's odd. Are you sure you're using Docusaurus v1 and not v2? – fralla Aug 08 '19 at 21:51
  • actually sry for my advice i checked it in pure React! not in Docusaurus! Really sorry! – lewa9 Aug 08 '19 at 21:52
  • Got you, that makes more sense. It appears there is no way of doing event handlers in Docusaurus v1 (see the GitHub issue I linked to in comments above). Thank you for your help anyways :) – fralla Aug 08 '19 at 21:54
  • I read the github comment! I recommened to try it with V2 of Docusaurus. Or a workaround to inject a jquery script which could handle the events! – lewa9 Aug 08 '19 at 21:55
  • Hmm yeah, might look into jQuery! If you see a way of doing it with jQuery, let me know :) – fralla Aug 08 '19 at 21:57
  • I would recommend not to try it with jQuery. This solution would be too nasty! – lewa9 Aug 08 '19 at 22:01
  • Please see my answer for an explanation why this isn't working. – Yangshun Tay Aug 08 '19 at 22:23