How can I prevent rerendering of child components on state update

Hello,

This is more a React related issue, but I could not solve it so far. I have a parentpage with multiple panels in a dashboard. The content of each panel gets loaded from a separate file to keep the code cleaner. The parent holds the datamangers and the datasets as well as several objectIDs (such as selectedProjectID, selectedSectionID, selectedChapterID, selectedPageID, selectedCommentID).

All IDs are defined like this:

const [selectedChapterID, setSelectedChapterID] = useState('');


I am currently struggling with following issue:

when a DropDownlist, ListView or ListBox of any of the child elements updates any ID, the parent rerenders the child component and the selection gets lost.

I managed to keep the selection with DropDownlist by setting its "value" to the selected ID, but could not achieve the same with ListView and ListBox.

I have to click twice on the ListView to actually select an Item and get its "select" function triggered properly.


When I put all functions into one single file and skip the parent-child file structure, the components do not get rerendered and I have my desired outcome. But I dont want a super long single file.


How can I prevent the components from the child files to rerender after an ID gets updated? I have tried callbacks, react.memo, but nothing worked so far.


Here is some sample code:

// Parent component
import React, { useState } from "react";
import ChildComponent from "./ChildComponent";

function ParentComponent() {
const [selectedProjectId, setSelectedProjectId] = useState("");

const handleProjectIdChange = (projectId) => {
setSelectedProjectId(projectId); //<--- this rerenders the ChildComponent which is NOT wanted
};

return (
<div>
<h1>Parent Component</h1>
<ChildComponent
selectedProjectId={selectedProjectId}
onProjectIdChange={handleProjectIdChange}
/>
<p>Selected project ID: {selectedProjectId}</p>
</div>
);
}

export default ParentComponent;


// Child component
import React, { useState } from "react";

function ChildComponent({ selectedProjectId, onProjectIdChange }) {
const [projectOptions, setProjectOptions] = useState([
{ id: "1", name: "Project 1" },
{ id: "2", name: "Project 2" },
{ id: "3", name: "Project 3" },
]);

const handleProjectChange = (event) => {
const projectId = event.target.value;
onProjectIdChange(projectId);
};

return (
<div>
<h2>Child Component</h2>
<select value={selectedProjectId} onChange={handleProjectChange}>
<option value="">Select a project</option>
{projectOptions.map((option) => (
<option key={option.id} value={option.id}>
{option.name}
</option>
))}
</select>
</div>
);
}

export default ChildComponent;



1 Reply

YA YuvanShankar Arunagiri Syncfusion Team May 24, 2023 06:04 AM UTC

Hi Mehdi,


Sorry for the inconvenience. We have checked your reported query and please refer to the below suggestion to resolve your issue.


Query: Listbox component related issue:


We have attempted to replicate the issue on our end but were unable to do so. We have prepared a sample based on your provided code snippet. And for list box value property, we need to assign the array type value shown as below.

API link: https://ej2.syncfusion.com/react/documentation/api/list-box/#value

const [selectedProjectIdsetSelectedProjectId] = useState([]);


Sample link: https://stackblitz.com/edit/react-6npyyv?file=index.js


Refer to the above sample link and if you still facing the issue, could you please share the issue replicable sample or replicate issue in our sampleBased on that we will check and provide you a better solution quickly.


Query: ListView component related issue:


The reported re-rendering issue occurs due to the state variable update with the ListView Template support. To resolve this, we recommend binding the statelessTemplates property in the ListView component. Refer to the below code snippet for your further reference.


<ListViewComponent

  dataSource={data}

  // select={onChildListViewSelect}

  statelessTemplates={['template']}

  template={(data) =>

    childMappingListViewItemTemplate(data, handleCheckboxChange)

  }

/>


Sample: https://stackblitz.com/edit/react-ovcqhh-y4ej1n?file=index.js


Regards,

YuvanShankar A


Loader.
Up arrow icon