1

I'm working on a small React project where I have two boxes: one for input and another for output. I want the input text to be displayed as rendered HTML in the output box. Essentially, I'm looking for the reverse of dangerouslySetInnerHTML.

Here's what I've tried so far, but it's not giving me the desired result:

import React, { useState, useEffect } from "react";
import "./InputOutput.css";

const InputOutput = () => {
  const [inputValue, setInputValue] = useState("");
  const [outputValue, setOutputValue] = useState("");

  useEffect(() => {
    const paragraphs = inputValue.split("\n").map((p) => p.trim());
    const htmlParagraphs = paragraphs.map((p) => {
      if (!p) return "<p>&nbsp;</p>";
      return `<p>${p.replace(/ /g, "&nbsp;")}</p>`;
    });
    setOutputValue(htmlParagraphs.join(""));
  }, [inputValue]);

  return (
    <div className="container">
      <div className="input-box">
        <h2>Text</h2>
        <textarea
          placeholder="Type here"
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
        />
      </div>
      <div className="output-box">
        <h2>HTML</h2>
        <div>{outputValue}</div>
      </div>
    </div>
  );
};

export default InputOutput;

Input:

Hello all, my name is Alex

This is one empty lane

These are 2 empty lanes

Expected Output:

<p>Hello all, my name is Alex</p>
<p>&nbsp;</p>
<p>This is one empty lane</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>These are 2 empty lanes</p>

Any suggestions on how to achieve this?

Thanks!

Showed on the question

Should be similar to Convert plain string to html in react

4
  • 1
    What does the current output look like? Commented Oct 2, 2023 at 12:54
  • Does this answer your question? Rendering raw html with reactjs Commented Oct 2, 2023 at 12:56
  • Why is htmlParagraphs an array of strings and not an array of react "p" elements? Commented Oct 2, 2023 at 13:16
  • Is this so you can see newlines etc, if so you could just set the div to render with a style of white-space: pre.. Commented Oct 2, 2023 at 13:42

2 Answers 2

1

you can define outputValue as component.

import React, { useState, useEffect } from "react";

const InputOutput = () => {
  const [inputValue, setInputValue] = useState("");
  const [outputValue, setOutputValue] = useState(<></>);

  useEffect(() => {
    const paragraphs = inputValue.split("\n").map((p) => p.trim());
    const htmlParagraphs = <>
    {
       paragraphs.map((p) => {
        if (!p) return <p>&nbsp;</p>;
        return <p>{p}</p>;
      })
    }
    </>
   
    setOutputValue(htmlParagraphs);
  }, [inputValue]);

  return (
    <div className="container">
      <div className="input-box">
        <h2>Text</h2>
        <textarea
          placeholder="Type here"
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
        />
      </div>
      <div className="output-box">
        <h2>HTML</h2>
        <div>{outputValue}</div>
      </div>
    </div>
  );
};

export default InputOutput;
Sign up to request clarification or add additional context in comments.

Comments

0

This is my solution, with map operator.

import React, { useState, useEffect } from 'react';
import './style.css';

const App = () => {
  const [inputValue, setInputValue] = useState('');
  const [outputValue, setOutputValue] = useState('');

  useEffect(() => {
    const paragraphs = inputValue.split('\n').map((p) => p.trim());
    const htmlParagraphs = paragraphs;
    setOutputValue(htmlParagraphs);
  }, [inputValue]);

  return (
    <div className="container">
      <div className="input-box">
        <h2>Text</h2>
        <textarea
          placeholder="Type here"
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
        />
      </div>
      <div className="output-box">
        <h2>HTML</h2>
        {outputValue &&
          outputValue.map((element) => (element ? <p> {element}</p> : <br />))}
      </div>
    </div>
  );
};

export default App;

stackblitz

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.