I'm using typescript. I'm having a column value in the table as
val desc = "<div><p>testing</p></div>"
I want to render this as testing
in value. I'm using
react-table
I tried new DOMParser().parseFromString("<div><p>testing</p></div>", "text/html")
But got error as
Error: Objects are not valid as a React child (found: [object HTMLDocument]). If you meant to render a collection of children, use an array instead
Here is my react-table code:
<Table
data={data}
headers={headers}
searchable={true}
searchPlaceholder={'Search Apps'}
toolBarButtons={toolBarButtons}
/>
const headers = useMemo(
() => [
{
Header: <LeftHeader>{checkbox}</LeftHeader>,
accessor: 'Checkbox',
disableSortBy: true,
},
{
Header: <LeftHeader>Name {sortIcon}</LeftHeader>,
accessor: 'Name',
},
{
Header: <LeftHeader>Type {sortIcon}</LeftHeader>,
accessor: 'Type',
},
{
Header: <LeftHeader>Tenancy {sortIcon}</LeftHeader>,
accessor: 'Tenancy',
},
{
Header: <LeftHeader>Description {sortIcon}</LeftHeader>,
accessor: 'Description',
},
{
Header: <LeftHeader>Action</LeftHeader>,
accessor: 'Button',
disableSortBy: true,
},
],
[],
)
const data = useMemo(() => {
return List.map((ap) => {
const actionButton = (
<Edit
size={20}
cursor={'pointer'}
color={'#1E95DE'}
onClick={() => setRedirectUrl(RouteConstants.Marketplace + '/' + ap.id)}
/>
)
checkbox = <input type={'checkbox'} onChange={(e) => handleInputChange(e, ap)} />;
return {
Checkbox: checkbox,
Name: ap.stuName,
Type: options.filter(e => e.value === ap.stuType).map(f => {
return f.label
}),
Description: ap.studescription,
Tenancy: titleCase(ap.stuTenancy),
Button: actionButton,
};
})
}, [List])
How can I achieve this?
I'm using typescript. I'm having a column value in the table as
val desc = "<div><p>testing</p></div>"
I want to render this as testing
in value. I'm using
react-table
I tried new DOMParser().parseFromString("<div><p>testing</p></div>", "text/html")
But got error as
Error: Objects are not valid as a React child (found: [object HTMLDocument]). If you meant to render a collection of children, use an array instead
Here is my react-table code:
<Table
data={data}
headers={headers}
searchable={true}
searchPlaceholder={'Search Apps'}
toolBarButtons={toolBarButtons}
/>
const headers = useMemo(
() => [
{
Header: <LeftHeader>{checkbox}</LeftHeader>,
accessor: 'Checkbox',
disableSortBy: true,
},
{
Header: <LeftHeader>Name {sortIcon}</LeftHeader>,
accessor: 'Name',
},
{
Header: <LeftHeader>Type {sortIcon}</LeftHeader>,
accessor: 'Type',
},
{
Header: <LeftHeader>Tenancy {sortIcon}</LeftHeader>,
accessor: 'Tenancy',
},
{
Header: <LeftHeader>Description {sortIcon}</LeftHeader>,
accessor: 'Description',
},
{
Header: <LeftHeader>Action</LeftHeader>,
accessor: 'Button',
disableSortBy: true,
},
],
[],
)
const data = useMemo(() => {
return List.map((ap) => {
const actionButton = (
<Edit
size={20}
cursor={'pointer'}
color={'#1E95DE'}
onClick={() => setRedirectUrl(RouteConstants.Marketplace + '/' + ap.id)}
/>
)
checkbox = <input type={'checkbox'} onChange={(e) => handleInputChange(e, ap)} />;
return {
Checkbox: checkbox,
Name: ap.stuName,
Type: options.filter(e => e.value === ap.stuType).map(f => {
return f.label
}),
Description: ap.studescription,
Tenancy: titleCase(ap.stuTenancy),
Button: actionButton,
};
})
}, [List])
How can I achieve this?
Share Improve this question edited Feb 28, 2021 at 11:17 Harshit Thakurr asked Feb 28, 2021 at 10:36 Harshit ThakurrHarshit Thakurr 4072 gold badges6 silver badges12 bronze badges 3-
Is there a reason why
desc
is defined as"<div><p>testing</p></div>"
(string) and not as<div><p>testing</p></div>
(React element)? If not, just remove the quotes and you should be fine. – 3limin4t0r Commented Feb 28, 2021 at 11:06 - yeah, there is a reason. It will be not just this much its like a description of any application – Harshit Thakurr Commented Feb 28, 2021 at 11:16
-
Does this question really belong to
react-table
? – Arvind K. Commented Mar 11, 2022 at 11:50
2 Answers
Reset to default 3You will have to use dangerouslySetInnerHTML which is unsafe, prone to XSS attack.
let desc = "<div><p>testing</p></div>"
// ...
<span dangerouslySetInnerHTML={{__html: desc}} />
// or in React Table Cell
{
Header: <LeftHeader>Description {sortIcon}</LeftHeader>,
accessor: 'Description',
Cell: ({row}) => <span dangerouslySetInnerHTML={{__html: row.original.Description}} />
},
You can do it if you trust the source of your HTML string. It should not be a user provided input.
You have two another choice here.
One of theme is to use states. I would like to remend you to use "redux".
For example (Using pure react states):
import React, {useState} from 'react';
export const App = props => {
const [desc, setDesc] = useState('<div><p>testing</p></div>');
return <element>{desc}</element>
}
And the other one is innerHTML by Ref or DOM:
import React, { useRef, useEffect } from 'react';
const desc = "<div><p>testing</p></div>";
export const App = props => {
const myRef = useRef(null);
useEffect(() => {
myRef.current.innerHtml = desc; //using Refs
//or
document.getElementById('myID').innerHTML = desc; //using DOM
}, [])
return <element id="myId" ref={myRef}>{desc}</element>
}