I have the following react text area component:
<Textarea
autoFocus
placeholder={(formState.commentBody && formState.commentBody !== '') ? formState.commentBody : intl.get('issue_details_placeholder_add_a_comment')}
value={formState.commentBody}
onChange={handleChange('commentBody')}
ref={$textareaRef}
/>
what gets displayed in the textarea is just formState.commentBody
and Textarea
is defined as:
import React, { forwardRef } from 'react';
import TextareaAutoSize from 'react-textarea-autosize';
import { StyledTextarea } from './Styles';
const Textarea = forwardRef(({ className, invalid, onChange, ...textareaProps }, ref) => (
<StyledTextarea className={className} invalid={invalid}>
<TextareaAutoSize
{...textareaProps}
onChange={event => onChange(event.target.value, event)}
ref={ref || undefined}
/>
</StyledTextarea>
));
export default Textarea;
Now, instead of passing a string (formState.commentBody
) as value into Textarea
, I want to pass some jsx code:
<blockquote>
this is a customizable text and clickable within textarea
</blockquote>
into <textarea>
as its children, such that it would be equivalent to :
<textarea>
<blockquote>
this is a customizable text and clickable within textarea
</blockquote>
</textarea>
The final goal is to be able to display block code inside the TextareaAutoSize
.
How can I achieve this?
I tried to code inside the TextareaAutoSize
component directly like this:
const Textarea = forwardRef(({ className, invalid, onChange, ...textareaProps }, ref) => (
<StyledTextarea className={className} invalid={invalid}>
<TextareaAutoSize
{...textareaProps}
onChange={event => onChange(event.target.value, event)}
ref={ref || undefined}
>
<blockquote>
hahaha
</blockquote>
</TextareaAutoSize>
</StyledTextarea>
));
export default Textarea;
However it is displaying:
Why is this happening?
CodePudding user response:
You can't embed html content in a textarea
(docs). To do this, you could consider using a content-editable div:
<div contenteditable="true">
<blockquote>hahaha</blockquote>
</div>
CodePudding user response:
Now, instead of passing a string (formState.commentBody) as value into Textarea, I want to pass some jsx code.
The value of a text area is a string (text), not markup (spec). Although you could use JSX to create content for it, you'd have to render those elements to a string in order to make them the value of a textarea (via ReactDOMServer.renderToString
or similar), like this:
const { useState } = React;
const Textarea = ({children, value, updateValue}) => {
if (typeof value === "undefined") {
value = ReactDOMServer.renderToString(children);
}
return (
<textarea value={value} onChange={() => {/*...*/}} />
);
};
const Example = () => {
return (
<Textarea>
<blockquote>
this is a customizable text and clickable within textarea
</blockquote>
</Textarea>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);
textarea {
width: 100%;
height: 4em;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom-server-legacy.browser.development.js"></script>
But there's no point in doing that vs. just creating a string in the first place, and it's not updateable. (I couldn't tell from the question whether you wanted to be able to update it...but it's a textarea
, so...) You'd have to pull apart the bits of it in order to then use those bits when recreating the element. A string would be updateable, so I'd suggest just using a string:
const { useState } = React;
const Textarea = ({value, updateValue}) => {
const onChange = ({currentTarget: {value}}) => {
updateValue(value);
};
return (
<textarea value={value} onChange={onChange} />
);
};
const initialCommentBody = `<blockquote>
this is a customizable text and clickable within textarea
</blockquote>`;
const Example = () => {
const [ commentBody, setCommentBody ] = useState(initialCommentBody);
return (
<Textarea value={commentBody} updateValue={setCommentBody} />
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);
textarea {
width: 100%;
height: 4em;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>