javascript - Como posso passar classes CSS para filhos em React e garantir que elas sobrescrevam a classe local do filho?
Eu tenho um componente <Parent /> com um único <Child />:
<Parent>
<Child />
</Parent>
Eu quero passar uma classe CSS do componente pai para o <Child />, então eu faço isso:
<Parent>
<Child className={ styles.pill } />
</Parent>
O <Child /> tem uma prop className e aplica a classe usando o pacote classnames, assim:
<div className={ classNames(styles.pill, props.className) } />
Mas você vê que o <Child /> tem uma classe chamada styles.pill com estes estilos:
.pill {
align-content: stretch;
align-items: center;
color: var(--grey__text--dark);
cursor: pointer;
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
}
A classe que o pai passou contém esses estilos:
.pill {
align-items: flex-end;
flex-flow: column wrap;
}
Com essa configuração, não posso garantir que os estilos passados pelo componente pai irão sobrescrever os estilos dentro do componente <Child />, que é exatamente o que eu quero que aconteça. Atualmente, você nunca sabe qual irá prevalecer sobre o outro. Parece aleatório a cada compilação do projeto.
Como posso garantir que as propriedades CSS na classe passadas pelo componente pai sobrescrevam quaisquer propriedades semelhantes no componente Filho?
Resposta #1
É uma questão de especificidade do CSS, existem muitas maneiras de garantir a substituição.
O truque do seletor múltiplo, para aumentar a especificidade você pode dobrar o tamanho do seletor duplicando o nome da classe, no seu caso,
.pill.pill { ...}será mais específico que o original e, portanto, substituirá o estilo.Uso de
!important, você pode especificar que na classe do pai, a declaração de.pillconterá!importantno final.Vários seletores diferentes, o componente pai passará diferentes
classNameadicionais, que o componente filho irá usar,.pill.parent-pill {...}, o pai passará a classe.parent-pillpara o filho.
Esses são apenas 3 jeitos fáceis de substituir os estilos dos filhos, há mais.
Resposta #2
Você pode usar Object.assign para mesclar um/muitos objetos em um objeto alvo, dando precedência a cada objeto subsequente:
const foo = { a: '1', b: '2' }
const bar = { a: '3' }
console.log(Object.assign(foo, bar));