简体   繁体   中英

How can I pass the "isActive" prop from NavLink to its children?

function NavigationLink({ to, title, exactPath, Icon }) {
  const resolved = useResolvedPath(to);
  const match = useMatch({
    path: resolved.pathname,
    end: exactPath,
  });
  const [active, setActive] = useState(false);

  return (
    <StyledNavLink linkSelected={match}>
      <NavLink
        to={to}
        style={({ isActive }) =>
          isActive ? setActive(true) : setActive(false)
        }
      >
        <Title>{title}</Title>
        <SelectedContainerIcon active={active}>
          <Icon />
        </SelectedContainerIcon>
      </NavLink>
    </StyledNavLink>
  );
}

Right now I am using this, using the "isActive" to change a state that is then passed to the child component (to change the icon's background color) but it is giving me a rendering error (despite actually working well). Is there a way to pass the "isActive" directly to the child?

In addition to taking a function callback for the className and style prop, the NavLink also takes a render function as the children prop.

Don't use the className or style props to issue side-effects like enqueueing state updates.

NavLink

declare function NavLink( props: NavLinkProps ): React.ReactElement; interface NavLinkProps extends Omit< LinkProps, "className" | "style" | "children" > { caseSensitive?: boolean; children?: | React.ReactNode | ((props: { isActive: boolean }) => React.ReactNode); className?: | string | ((props: { isActive: boolean; }) => string | undefined); end?: boolean; style?: | React.CSSProperties | ((props: { isActive: boolean; }) => React.CSSProperties); }

Your code:

function NavigationLink({ to, title, exactPath, Icon }) {
  const resolved = useResolvedPath(to);
  const match = useMatch({
    path: resolved.pathname,
    end: exactPath,
  });

  return (
    <StyledNavLink linkSelected={match}>
      <NavLink to={to}>
        {({ isActive }) => (
          <>
            <Title>{title}</Title>
            <SelectedContainerIcon active={isActive}>
              <Icon />
            </SelectedContainerIcon>
          </>
        )}
      </NavLink>
    </StyledNavLink>
  );
}

Dynamically render a className based on the isActive property, instead of the style attribute, and use CSS descendent selectors to change children of the active class.

<NavLink 
  to={to} 
  className={({ isActive }) => isActive ? "active" : "" }
>
  <Title>{title}</Title>
  <SelectedContainerIcon>
    <Icon />
  </SelectedContainerIcon>
</NavLink>
.active i {
  background-color: blue
}

With this solution it probably won't be necessary to save the active status to state. CSS will do the logic for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM