Search code examples
reactjsiframerenderingtableau-api

React tableau visualization component doesn't rerender when path prop changes


I have a webpage that displays a react component, TableauReports, which shows a tableau dashboard. This is the TableaReports component:

const TableauReports = ({ selectedBtn }) => {

    console.log(`selectedBtn = ${selectedBtn}`)

    return (
      <div className='tableauPlaceholder' style={{ width: '1400px', height: '950px' }}>
        <object className='tableauViz' width='1400' height='950' style={{ display: 'none' }}>
          <param name='host_url' value='https%3A%2F%2Ftableauanalytical-east.cloud.privateSite.com%2F' />
          <param name='embed_code_version' value='3' />
          <param name='site_root' value='&#47;t&#47;A_B_C' />
          <param name='name' value={`Reports/${selectedBtn.replace(" ", "")}`} />
          <param name='tabs' value='yes' />
          <param name='toolbar' value='yes' />
          <param name='showAppBanner' value='false' />
        </object>
      </div>
    )
  }

export default TableauReports

And within my app.jsx the component is accessed like so:

const [selectedTableauBtn, setSelectedTableauBtn] = useState(constants.TableauButtons[2]);

// some code that sets the selectedTableauBtn... 

<TableauReports selectedBtn={selectedTableauBtn}></TableauReports>

The component indeed is accessed every time selectedTableauBtn changes as the console.log in TableauReports is triggered and it prints the correct value. The problem is: the tableau dashboard doesn't switch tabs as it should. In fact, the dashboard doesn't rerender at all! Why isn't the dashboard rerendering and displaying the updated visualization as specified by the input selectedBtn?


Solution

  • Looking some Tableau docs here regarding embedded code they seem to use &#47; as a delimiter.

    Example:

    <object class='tableauViz' width='800' height='600' style='display:none;'>
       <param name='host_url' value='https%3A%2F%2Fonline.tableau.com%2F' /> 
       <param name='site_root' value='&#47;t&#47;Sales' /> 
       <param name='name' value='MyCoSales&#47;SalesScoreCard&#47;' /> 
       <param name='tabs' value='yes' /> 
       <param name='toolbar' value='yes' />
    </object>
    

    Given that I can't find much of any documentation regarding Tableau's embedding coding syntax I suggest matching the syntax.

    <param name='name' value={`Reports&#47;${selectedBtn.replace(" ", "")}&#47;`} />
    

    If this fails to get the iframe to refresh then you may just need a bigger hammer to force remount the element using a React key.

    const TableauReports = ({ selectedBtn }) => {
      console.log({ selectedBtn });
    
      return (
        <div
          className='tableauPlaceholder'
          style={{ width: '1400px', height: '950px' }}
        >
          <object
            key={selectedBtn} // <-- key to remount `object`
            className='tableauViz'
            width='1400'
            height='950'
            style={{ display: 'none' }}
          >
            <param
              name='host_url'
              value='https%3A%2F%2Ftableauanalytical-east.cloud.privateSite.com%2F'
            />
            <param name='embed_code_version' value='3' />
            <param name='site_root' value='&#47;t&#47;A_B_C' />
            <param
              name='name'
              value={`Reports&#47;${selectedBtn.replace(" ", "")}&#47;`}
            />
            <param name='tabs' value='yes' />
            <param name='toolbar' value='yes' />
            <param name='showAppBanner' value='false' />
          </object>
        </div>
      )
    }