Home > Blockchain >  How do I map different arrays based on state?
How do I map different arrays based on state?

Time:01-25

I currently have a toggle button. When false, it should hide the red cards (late jobs) in it's column. When true, all jobs should be shown. However it is not working. The state changes, but no re render happens.

const App = () => {
  const [showLateJobs, setShowLateJobs] = useState(true);
  const [user, setUser] = useState("default");
  const multipleUsersArray = [...otherUser, ...AllJobs];

  let toOrderArray =
    user === "default"
      ? AllJobs.filter((job) => job.category === "to_order")
      : multipleUsersArray.filter((job) => job.category === "to_order");

  let toOrderArrayNoLate =
    user === "default"
      ? AllJobs.filter((job) => job.category === "to_order" && job.late != true)
      : multipleUsersArray.filter(
          (job) => job.category === "to_order" && job.late != true
        );

  const [toOrderState, setToOrderState] = useState(
    showLateJobs ? toOrderArray : toOrderArrayNoLate
  );

  return (
    <>
      <Toggle
        defaultChecked={true}
        onChange={(e) => {
          if (!e.target.checked) {
            setShowLateJobs(false);
            console.log("toggled");
          } else {
            setShowLateJobs(true);
          }
        }}
      />

      <Column>
        {toOrderState.map((job, index) => (
          <JobCard
            job_number={job.jobNumber}
            time={job.time}
            cardHeight={layout === "extended" ? "150px" : "50px"}
            layout={layout}
            backgroundColor={job.late && "#D64045"}
            displayLateIcon={job.late && "block"}
          />
        ))}
      </Column>
    </>
  );
};

CodePudding user response:

The issue is that you're setting your computed values into state as initial values. Since you're never calling setToOrderState(...), the state value never changes.

If you'd like to derive new state from existing state, you can use a memo hook

// Define these outside your component
// so they're not re-initialised every render
const DEFAULT_USER = "default";
const CATEGORY_FILTER = "to_order";

const multipleUsersArray = [...otherUser, ...AllJobs];

const filterPredicate =
  (includeLate) =>
  ({ category, late }) =>
    category === CATEGORY_FILTER && (includeLate || !late);
// And these inside your component
const [showLateJobs, setShowLateJobs] = useState(true);
const [user, setUser] = useState(DEFAULT_USER);

const toOrderState = useMemo(
  () =>
    (user === DEFAULT_USER ? AllJobs : multipleUsersArray).filter(
      filterPredicate(showLateJobs)
    ),
  [user, showLateJobs] // hook dependencies
);

  • Related