Search code examples
javascriptreactjsemotion

Why are props being shared between seperate instances of an emotion-js component?


  1. Why does emotion-js appear to share the props from seperate component instances?
<Button isDisabled={'true'} />
<Button />
const Button = styled.button`
  background-color: ${props => props.isDisabled !== 'true' ? 'green' : 'grey'};
`;
export default (props) => {
    return (<Button>Hello</Button>);
}

Expectation: The first <Button/> is grey. The second is green.

Reality: Both instances of <Button/> are grey.


Also, this one had me very confused until I noticed this snippit from the docs:

By default, Emotion passes all props to custom components and only props that are valid html attributes for string tags.

  1. Why pass only props that are valid string tags? The following use of bool seems like it would be a valid use case.
<Button isDisabled={true} /> 

Solution

  • It does not share props. You just need to pass them properly. There are two ways to achieve what you want, either do it with proper strings or with boolean values:

    String version:

    const Button = styled('button')`
      background-color: ${props => props.isDisabled !== 'true' ? 'green' : 'grey'};
    `;
    

    Usage:

    <Button isDisabled="true">grey</Button>
    <Button>green</Button>
    

    Or with bool values (what might be preferable in this case):

    const Button = styled('button')`
      background-color: ${props => props.isDisabled ? 'grey' : 'green'};
    `;
    

    Usage:

    <Button isDisabled>Grey</Button>
    <Button>green</Button>