I'm facing a problem there is a styled component named Breadcrumb but that component depends upon 1 separate styled-components i.e BreadcrumbItem. Both components have different props.
BreadcrumbItem.js:
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
const propTypes = {
  /** Active the current BreadcrumbItem. */
  active: PropTypes.bool,
  /** Additional classes. */
  className: PropTypes.string
};
const AbstractBreadcrumbItem = (props) => {
  const { className, active, ...attributes } = props;
  return <li {...attributes} className={className} />;
};
AbstractBreadcrumbItem.propTypes = propTypes;
const BreadcrumbItem = styled(AbstractBreadcrumbItem)``;
BreadcrumbItem.propTypes = propTypes;
export default BreadcrumbItem;
Breadcrumb.js:
import React from "react";
import styled from "styled-components";
import PropTypes from "prop-types";
const propTypes = {
  /** Additional classes. */
  className: PropTypes.string,
  /** Primary content. */
  children: PropTypes.node,
  /** Custom separator */
  separator: PropTypes.string,
  /** Change the look and feel of the BreadcrumbItem. */
  scheme: PropTypes.oneOf(["red", "purple"]).isRequired
};
const defaultProps = {
  scheme: "red",
  separator: "/"
};
const AbstractBreadcrumb = props => {
  const { className, children, separator, scheme, ...attributes } = props;
  return (
    <ul {...attributes} className={className}>
      {children}
    </ul>
  );
};
AbstractBreadcrumb.propTypes = propTypes;
AbstractBreadcrumb.defaultProps = defaultProps;
const Breadcrumb = styled(AbstractBreadcrumb)`
              display: flex;
              flex-wrap: wrap;
              padding: 18px 26px;
              margin-bottom: 1rem;
              list-style: none;
              background-color: #fbfbfb;
              border-radius: 4px;
              li + li:before {
                content: "${props => props.separator}";
              }
              li + li {
                padding-left: 8px;
            }
              li + li::before {
              display: inline-block;
              padding-right: 0.5rem;
            }
            li a {
               font-size: 14px;
               transition: color .4s linear;
               color: ${props => (props.scheme === "red" ? "red" : "purple")};
               &:hover {
                color: black;
               }
            }
`;
Breadcrumb.propTypes = propTypes;
Breadcrumb.defaultProps = defaultProps;
export default Breadcrumb;
This is the main markup to create the Breadcrumb.
App.js:
import React from 'react';
import Breadcrumb from './Breadcrumb';
import BreadcrumbItem from './BreadcrumbItem';
export default function App() {
  return (
    <div className="App">
      <Breadcrumb scheme="red">
        <BreadcrumbItem>
          <a href="/">Home</a>
        </BreadcrumbItem>
        <BreadcrumbItem>
          <a href="/">Shop</a>
        </BreadcrumbItem>
        <BreadcrumbItem active>
          <a href="/">Product</a>
        </BreadcrumbItem>
      </Breadcrumb>
    </div>
  );
}
What problem I'm facing is I want to use the active prop of the BreadcrumbItem component inside the parent Breadcrumb component to change the look and feel of the item according to the scheme.
I found the first way which is to add the BreadcrumbItem styles inside the component itself and use something like this ${props => props.active ? css`` : css``}. But Is there a way in styled-component to access the child component prop inside the Parent component?
Please answer the question in the context of styled-components.
Live link: Codesandbox
In React we can access the child's state using Refs. we will assign a Refs for the child component in the parent component. then using Refs we can access the child's state. Creating Refs Refs are created using React.
To pass data from a child component to its parent, we can call a parent function from the child component with arguments. The parent function can be passed down to the child as a prop, and the function arguments are the data that the parent will receive.
I'd suggest to move the styling of list item, i.e. <li>, to its own component, i.e. BreadcrumbItem. In this scenario you won't need to access the state of child component instead you'll be handling active state in <li> styles. And it'll look more cleaner and separation of concern (which React recommends) will be there.
[EDIT]: Sample code to access props of children
const List = ({ children }) => {
  return (
    <ul>
      {React.Children.map(children, x => {
        console.log(x.props); // get props of children
        return x;
      })}
    </ul>
  );
};
const Item = ({ children }) => <li>{children}</li>;
export default function App() {
  return (
    <List>
      <Item>Hello</Item>
      <Item active>HI</Item>
    </List>
  );
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With