Home > Software engineering >  setting react state when clicking on a functional component via onClick (TypeScript)
setting react state when clicking on a functional component via onClick (TypeScript)

Time:05-20

const NavBar = () => {
    const [active, setActive] = useState<string>("tasks");

    return {
        <Container>
            <MenuLink onClick=(() => setActive("settings")/>
            <MenuLink onClick=(() => setActive("tasks")/>
            <MenuLink onClick=(() => setActive("wallets")/>
        </Container>
    }

MenuLink.tsx:

interface MenuLinkProps {
  $active: boolean;
  to: string;
  title: string;
}

function MenuLink({ $active, to, title, ...rest }: MenuLinkProps) {
  return (
    <Container $active={$active} to={to} {...rest}>
      {title}
    </Container>
  );
}

interface ContainerProps {
  $active: boolean;
  to: string;
}

const Container = styled(Link)<ContainerProps>`
  width: 70px;
  height: 35px;

  display: flex;
  justify-content: center;
  align-items: center;

  border-radius: 3px;

  font-style: normal;
  font-weight: 500;
  font-size: 14px;
  line-height: 17px;
  letter-spacing: 0.025em;

  text-decoration: none;

  color: ${({ $active }: ContainerProps) => ($active ? "#4C6C94" : "#908E87")};
  background: ${({ $active }: ContainerProps) => ($active ? "#1D232B;" : "#100F0D")};

  &:not(:first-child) {
    margin-left: 24px;
  }
`;

I want to fire off setActive whenever a MenuLink item is clicked. However, TypeScript is complaining that I don't have onClick as an attribute in MenuLinkProps. I'm not sure if this is correct as when I do put onClick as an attribute, I get this error:

Cannot update a component (`NavBar`) while rendering a different component (`MenuLink`). To locate the bad setState() call inside `MenuLink`, follow the stack trace as described in

I'm not too sure how I should go about using onClick (and other standard "props") in custom components.

CodePudding user response:

you can change your interface of NavBar to

interface MenuLinkProps {
  $active: boolean;
  to: string;
  title: string;
  [key : string] : any
}

to accept any props at rest This will not fix your error, please provide where and how do you use $active

CodePudding user response:

So, You will have to pass the parent click method to the child as a props

Parent component :

const NavBar = () => {
  const [active, setActive] = useState<string>("tasks");


  var menuOnClick: (action:string) => {setActive(action)};


  return {
    <div>
      <Container>
          <MenuLink onClick=(this.menuOnClick} />
          <MenuLink onClick=(this.menuOnClick} />
          <MenuLink onClick=(this.menuOnClick} />
      </Container>
    </div>
  }
}

Child component :

<Container $active={$active} to={to} {...rest} onClick ={() => this.props.onClick(title)} >
{title}
</Container>
  • Related