Melhorando a legibilidade de if's ternários no JSX
Uma forma muito interessante de fazer rendarizações condicionais é usar um if ternário, porém quando estamos trabalhando em componentes com muitos elementos visuais essa estratégia pode deixar o nosso código confuso e poluído... Veja nesse exemplo:
export const ReactPage: React.FC = () => {
const [randomNumber, setRandomNumber] = useState(0);
return (
<div>
<h1>Melhorando ifs ternários</h1>
{randomNumber === 0 ? (
<div>
<span>Igual a zero</span>
<button
onClick={() => setRandomNumber(Math.floor(Math.random() * 100))}
>
Alterar número
</button>
<footer>
<nav>
<a href="/">Voltar</a>
</nav>
</footer>
</div>
) : (
<></>
)}
</div>
);
};
Uma estratégia interessante para resolver esse problema é criar um componente que irá ajudar a deixar o código mais limpo, e poderá ser reutilizado em todo o projeto. Vamos dar uma olhada:
interface RenderIfProps {
condition: boolean;
}
export const RenderIf: React.FC<RenderIfProps> = ({condition}, children) => {
return condition ? children : <></>;
};
Agora, vamos usar esse componente e refatorar o primeiro exemplo:
export const ReactPageRefactored: React.FC = () => {
const [randomNumber, setRandomNumber] = useState(0);
return (
<div>
<h1>Melhorando ifs ternários</h1>
<RenderIf condition={randomNumber === 0}>
<div>
<span>Igual a zero</span>
<button
onClick={() => setRandomNumber(Math.floor(Math.random() * 100))}
>
Alterar número
</button>
<footer>
<nav>
<a href="/">Voltar</a>
</nav>
</footer>
</div>
</RenderIf>
</div>
);
};
Talvez você possa não ver muitas vantagens em utilizar esta abstração, pois o código do exemplo é pequeno para facilitar a didática. Porém no dia a dia, este tipo de componente pode ajudar muito e melhorar a qualidade do código de todo o seu projeto.
Abordagem interessante Leonardo!
Isso me lembrou a estratégia do &&
que é usada aqui mesmo nessa página:
Tem duas situações ali:
- Mostrar o confete se for um post novo.
- Mostrar um link no topo se esse conteúdo tiver um
parent_id
Tive a impressão de haver um pequeno erro aqui:
Uma estratégia interessante para resolver esse problema é criar um componente que irá ajudar a deixar o código mais limpo, e poderá ser reutilizado em todo o projeto. Vamos dar uma olhada:
interface RenderIfProps {
condition: boolean;
}
export const RenderIf: React.FC<RenderIfProps> = ({condition}, children) => {
return condition ? children : <></>;
};
Mais precisamente na declaração da função RenderIf
, acredito que children seja uma propriedade do objeto que ela recebe como primeiro parâmetro, e não segundo parâmetro. Tentei copiar o código do jeito que está aqui, e acabei tendo um erro:
Unhandled Runtime Error
Error: Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead.
Assim passou a funcionar:
import React, { ReactElement } from 'react'
interface RenderIfProps {
condition: boolean
children: ReactElement<any, any>
}
export const RenderIf: React.FC<RenderIfProps> = ({ condition, children }) => {
return condition ? children : <></>
}