Search code examples
reactjstypescriptreduxredux-toolkitreact-typescript

Binding multipal row hang or crash web page using React with redux toolkit


https://codesandbox.io/s/large-data-array-with-redux-toolkit-forked-7tp63?file=/demo.tsx

In the given codesandbox example I am using react typescript with redux-toolkit

in codesandbox example. I am trying to bind countries with checkbox and textbox. When I check on checkboxes it looks slow and textbox edit also feels very slow. some time it breaks the page.

I am not sure what I am doing wrong.


Solution

  • You should make CountryItem it's own component and make it a pure component:

    import React, { FC, useEffect } from "react";
    import { createStyles, Theme, makeStyles } from "@material-ui/core/styles";
    import List from "@material-ui/core/List";
    import ListItem from "@material-ui/core/ListItem";
    import ListItemText from "@material-ui/core/ListItemText";
    import { countryList } from "./dummyData";
    import { Checkbox, Grid, TextField } from "@material-ui/core";
    import { useAppDispatch, useAppSelector } from "./store/hooks";
    import {
      setCountries,
      setCountrySelected,
      setCountryValue
    } from "./store/slice/geography-slice";
    import { Country } from "./interface/country.modal";
    
    const useStyles = makeStyles((theme: Theme) =>
      createStyles({
        root: {
          width: "100%",
          backgroundColor: theme.palette.background.paper
        }
      })
    );
    const CountryItem: FC<{ country: Country }> = ({ country }) => {
      console.log('render item',country.name)
      const dispatch = useAppDispatch();
      const handleCheckboxChange = (
        event: React.ChangeEvent<HTMLInputElement>,
        country: Country
      ) => {
        const selectedCountry = { ...country, isSelected: event.target.checked };
        dispatch(setCountrySelected(selectedCountry));
      };
    
      const handleTextChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        const selectedCountry = { ...country, value: event.target.value };
        dispatch(setCountryValue(selectedCountry));
      };
    
      return (
        <ListItem button>
          <Checkbox
            checked={country?.isSelected ?? false}
            onChange={(event) => {
              handleCheckboxChange(event, country);
            }}
          />
          <ListItemText primary={country.name} />
          <TextField value={country?.value ?? ""} onChange={handleTextChange} />
        </ListItem>
      );
    };
    const PureCountryItem = React.memo(CountryItem)
    export default function SimpleList() {
      const classes = useStyles();
      const dispatch = useAppDispatch();
      const { countries } = useAppSelector((state) => state.geography);
    
      useEffect(() => {
        dispatch(setCountries(countryList));
      }, []);
    
      return (
        <div className={classes.root}>
          <Grid container>
            <Grid item xs={6}>
              <List component="nav" aria-label="secondary mailbox folders">
                {countries.map((country, index) => (
                  <PureCountryItem country={country} key={`CountryItem__${index}`} />
                ))}
              </List>
            </Grid>
          </Grid>
        </div>
      );
    }