Home > Blockchain >  React dynamically added components not rendered
React dynamically added components not rendered

Time:12-14

I'm dynamically adding instances of a custom (Kendo-React) component into an array in my main App.

The component:

    const PersonDD = () => {
      const ages = ["Child", "Adult", "Senior"];
      return (
        <div>
          <div>Person:</div>
          <DropDownList
            data={ages} style={{   width: "300px",  }} 
          />
        </div>
      );
    };

I'm adding one instance on initial render, and another two instances after the result from an Ajax call returns.

const SourceTab = (SourceTabProps) => {

     ....

  var componentList = [];
  componentList.push(<PersonDD/>);

  async function getStrata(){
    var url = '/access/.im.read';
    const res = await axios.get(  url  );
    console.log(res.data.item);
    componentList.push(<PersonDD/>);
    componentList.push(<PersonDD/>);
  }

  React.useEffect(() =>{
    getStrata();
  },[]);

  return (
    <Title title="People" />
     <div className='assignment_div_css'>
      {componentList}
     </div>);
};

The problem I have is that the one instance in the initial array are rendered, but the two created after the Ajax call are not rendered.

Do I need to call .render() or something similar to refresh?

CodePudding user response:

You can simply use react useState to rerender component and in jsx map them.

like this :

const SourceTab = (SourceTabProps) => {


  const [componentList,setComponentList] = useState([PersonDD])
  

  async function getStrata(){
    var url = '/access/.im.read';
    const res = await axios.get(  url  );
    console.log(res.data.item);
    setComponentList([...componentList,PersonDD,PersonDD])

  }

  React.useEffect(() =>{
    getStrata();
  },[]);

  return (
    <Title title="People" />
  <div className='assignment_div_css'>
    {componentList.map((Component,index)=> <Component  key={index} />)}
  </div>);
};

CodePudding user response:

  1. You need to remember that React only re-renders (refreshes the UI/view) when a state changes. Your componentList is not a state at the moment but just an ordinary variable. make it a state by using useState hook.
  2. Not sure if it is a bad practice or not but I haven't seen any react project that keeps an entire component as a state so instead of creating a state with an array of components, just push a data representation of the components you want to render. Then display the component list using your list and using .map

Here's how it would look like.


     ....
   const [personList, setPersonList] = useState([1]);
  

  async function getStrata(){
    var url = '/access/.im.read';
    const res = await axios.get(  url  );
    setPersonList(state => state.push(2)); //you can make this dynamic so it can rerender as much components as you like, for now im pushing only #2
  }

  React.useEffect(() =>{
    getStrata();
  },[]);

  return (
    <Title title="People" />
     <div className='assignment_div_css'>
      {personList.map((item, key) => <PersonDD key={key} />)}
     </div>);
};

CodePudding user response:

Need to use the map to render a list

<div className='assignment_div_css'>
       {componentList.map(component => <>{component}</>)}
 </div>);

also, use a usestate to variable

const [componentList , setComponentList ]= React.useState[<PersonDD/>]; 

inside function set like this

console.log(res.data.item);
setComponentList(state => [...state, <PersonDD/>, <PersonDD/>]);
  • Related