Skip to content

React issue with show / hiding elements

This project is using React.

The goal is that when the maximize icon is clicked on the the Editor component, the Preview component will be hidden. When the maximize icon is clicked on the Preview component, the Editor component will be hidden.

The problem is, when I click the maximize icon on the Editor component, the only thing that displays is the text “not found.” But the Preview maximize icon works when clicked.

I logged state to the console so I know that the state is updating when the editor button is clicked, but I can’t figure out what is wrong with the way I am rendering the Editor element.

Codepen link: https://codepen.io/Jamece/pen/Exbmxmv

Thank you for any help you can provide.

import * as marked from "https://cdn.skypack.dev/marked@4.0.12";

class Application extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      editorOnly: false,
      previewOnly: false,
      inputValue: "",
      outputValue: ""
    };
    this.handleChange = this.handleChange.bind(this);
    this.editorChange = this.editorChange.bind(this);
    this.previewChange = this.previewChange.bind(this);
  }

  handleChange(event) {
    this.setState({
      inputValue: event.target.value
    });
  }
  //changes view to editorOnly when editor maximize button is clicked then back to full view when clicked again
  editorChange() {
    this.setState((state) => {
      if (state.editorOnly === false) {
        return { editorOnly: true };
      } else {
        return { editorOnly: false };
      }
    });
  }
  //changes view to previewOnly when preview maximize button is clicked then back to full view when clicked again
  previewChange() {
    this.setState((state) => {
      if (state.previewOnly === false) {
        return { previewOnly: true };
      } else {
        return { previewOnly: false };
      }
    });
  }

  render() {
    console.log(this.state);

    if (this.state.editorOnly === false && this.state.previewOnly === false) {
      return (
        <div className="container-fluid px-0">
          <div className="d-flex flex-column main">
            <Editor editorChange={this.editorChange} 
              handleChange={this.handleChange}/>
            <Preview previewChange={this.previewChange} />
          </div>
        </div>
      );
    } else if (
      this.state.editorOnly === true &&
      this.state.previewOnly === false
    ) {
      return (
          <div className="container-fluid px-0">
          <div className="d-flex flex-column main">
            <Editor editorChange={this.editorChange}
              handleChange={this.handleChange}/>
          </div>
        </div>
      );
    } else if (
      this.state.editorOnly === false &&
      this.state.previewOnly === true
    ) {
      return (
        <div className="container-fluid px-0">
          <div className="d-flex flex-column main">
            <Preview previewChange={this.previewChange} />
          </div>
        </div>
      );
    }
    else {
      return(
      <div></div>
      )
    }
  }
}
class Editor extends React.Component {
      constructor(props) {
        super(props);
      }
      render() {
        return (
          <div className="d-flex justify-content-center">
            <form>
              <div className="boxes">
                <div className="d-flex align-items-center label-bar">
                  <div className="leftcon">
                    <i className="fa-solid fa-book"></i>
                  </div>
                  <div className="headings">Editor</div>
                  <div className="rightcon">
                    <button className="btn" onClick={this.props.editorChange}>
                      <i className="fa-solid fa-maximize"></i>
                    </button>
                  </div>
                </div>
                <textarea
                 value={this.props.inputValue}
                  onChange={this.props.handleChange}
                ></textarea>
              </div>
            </form>
          </div>
        );
      }
}
class Preview extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <div className="d-flex justify-content-center">
          <form>
            <div className="boxes">
              <div className="d-flex align-items-center label-bar">
                <div className="leftcon">
                  <i className="fa-solid fa-book"></i>
                </div>
                <div className="headings">Preview</div>
                <div className="rightcon">
                  <button className="btn" onClick={this.props.previewChange}>
                    <i className="fa-solid fa-maximize"></i>
                  </button>
                </div>
              </div>
              <div className="preview">
                <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
              </div>
            </div>
          </form>
        </div>
      </div>
    );
  }
}
    
ReactDOM.render(<Application />, document.getElementById("app"));

Answer

A button element inside a form element by default has type="submit". Hence, when you click the maximize button it tries to submit the form, making an http request.

This is not what you want here so you should set type="button" on your buttons. This way they will not trigger a form submission on click.

The same thing happens on your Preview component, but note that in the console you get the following message:

Form submission canceled because the form is not connected

I believe this is because the way you order the elements in the different states causes React to recreate the preview window in the DOM. If you switch Editor and Preview around in the state where both are visible then Editor works fine and Preview is broken.