Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

render string as html in cell of react-table

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?

like image 235
Harshit Thakurr Avatar asked Sep 12 '25 16:09

Harshit Thakurr


2 Answers

You 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.

like image 147
Ajeet Shah Avatar answered Sep 14 '25 04:09

Ajeet Shah


You have two another choice here.

One of theme is to use states. I would like to recommend 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>
}
like image 31
qafoori Avatar answered Sep 14 '25 05:09

qafoori