0

I have a React + TS application and I'm writing a custom hook to update the header of a table. Basically, I can click on different checkboxes and hide/show that specific column of the table.

const useHeader = (headerConfiguration: TableHeader[]) => {
  const [header, setHeader] = useState(headerConfiguration);

  const updateHeader = (column: string) => {
     setHeader(prevState => {                       // <- this line has the error
       prevState.forEach(el => {
         if (el.name === column) el.visible = !el.visible;
       });
     });
  };

  return {
    header,
    updateHeader,
  };
};

export default useHeader;

As the code shown, I need to update the visible property based on the column name.

Currently I have an error tough:

Argument of type '(prevState: TableHeader[]) => void' is not assignable to parameter of type 'SetStateAction<TableHeader[]>'.
Type '(prevState: TableHeader[]) => void' is not assignable to type '(prevState: TableHeader[]) => TableHeader[]'. Type 'void' is not assignable to type 'TableHeader[]'.

I get what the error is saying but I'm not sure how to fix it, if I write the same function using the library Immer it works without any error:

   setHeader(
     produce(header, draftHeader => {
       draftHeader.forEach(el => {
         if (el.name === column) {
           el.visible = !el.visible;
         }
       });
     }),
   );

How can I fix this?

0

2 Answers 2

2

When not using immer, you're responisble to produce and return a new state. So instead of manipulating prevState you need to create a copy of it, with the changes you require applied.

For example, with something like this:

const updateHeader = (column: string) => {
  setHeader(prevState => {
    // return a copy prevState
    return prevState.map(
      el => el.name === column
        ? {...el, visible: !el.visible} // copy inner item, if changed
        : el;
    );
  });
};
Sign up to request clarification or add additional context in comments.

Comments

0

Please try this:

const useHeader = (headerConfiguration: TableHeader[]) => {


const [header, setHeader] = useState(headerConfiguration);



const updateHeader = (column: string) => {
    header.forEach(el => {
      if (el.name === column) el.visible = !el.visible;
    });
    setHeader(header);
  };

  return {
    header,
    updateHeader,
  };
};

export default useHeader;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.