Search code examples
javascripthtmlreactjsreact-hooksreact-bootstrap

use varibles with module in JS to HTML


I tried two way for the result, and none of it worked.

function GetData(){

   ... some process  // need to get data from other files online - 
                     // result is :
    //accordionData = [{name : 'foo', age : '1', count : 0 },{name: 'bar', age : '2', count : 1}]

   GenAccordion();
}

function GenAccordion(accordionData){
   let dataHTML = "<Accordion>";
   accordionData.forEach((data) => {
      dataHTML += `
      <Accordion.Item eventKey="${data.count}">
      <Accordion.Header>${data.name}</Accordion.Header>
      <Accordion.Body>${data.age}</Accordion.Body>
      </Accordion.Item>
      `
   }
   accordionData+="</Accordion>";
   document.querySelector(".appendAccordion").append(accordionData);
}

GetData();

return(
<>
<div id="appendAccordion"></div>
</>
);

I tried append, innerHTML, insertAdjacentHTML... and none of it worked and found out turned to , the lower letter, or the dataHTML content (code) is literally be printed.

So I tried other way,

const accordionData=[];

function .... // push data to accordionData
//Result is [{name : 'foo', age : '1', count : 0 },{name: 'bar', age : '2', count : 1}]


return(
<>
<div>
   <Accordion>
      {accordionList.map((data)=>{
         return (
            <Accordion.Item eventKey={data.count}>
            <Accordion.Header>{data.name}</Accordion.Header>
            <Accordion.Body>{data.age}</Accordion.Body>
            </Accordion.Item>
            )
         })
      }
   </Accordion>
</div>
</>
);

And there's problem also.

Return is faster than get data with function so nothing is printed but after rendering the page, there are datas in accordionData. (I checked with console.log)


So Here are my questions

  • first code ) is there any way to make the object variable with capital letters module in JS to be shown in HTML?
  • second code ) is there any way to rerender or sync {...map()} after the getting data?

Thanks.


Solution

  • const accordionData=[];
    
    function .... // push data to accordionData
    //Result is [{name : 'foo', age : '1', count : 0 },{name: 'bar', age : '2', count : 1}]
    
    
    return(
    <>
    <div>
       <Accordion>
          {accordionList.map((data)=>{
             return (
                <Accordion.Item eventKey={data.count}>
                <Accordion.Header>{data.name}</Accordion.Header>
                <Accordion.Body>{data.age}</Accordion.Body>
                </Accordion.Item>
                )
             })
          }
       </Accordion>
    </div>
    </>
    );
    

    so this way you are doing it is actually the way to go the only thing you should do is to put the data that you are receiving to the state of the component so then react knows that the state has been changed and rerender your component so this is what you should do like this

    const [accordionData, setAccordionData] = useState([])
        const theFunctionToGetTheData = () => {
          const data = getData() // actual function
          // that fetch the data, make sure if this function is async to use await
          // to await the promise like this "const data = getData()"
          setAccordionData(data)
        }
        return(
    <>
    <div>
       <Accordion>
          {accordionList.map((data)=>{
             return (
                <Accordion.Item eventKey={data.count}>
                <Accordion.Header>{data.name}</Accordion.Header>
                <Accordion.Body>{data.age}</Accordion.Body>
                </Accordion.Item>
                )
             })
          }
       </Accordion>
    </div>
    </>
    );
    

    Note: if you want to load the data on mount push the function (theFunctionToGetTheData) in useEffect