Agora estamos prontos(as) para criar o estado concreto do Fokus.
Já temos um primeiro ponto que gostaria de destacar. Vamos tomar alguns cuidados durante toda a escrita desta aplicação com a programação funcional.
Vamos trazer alguns conceitos dela para o nosso código. Um deles é que as funções deveriam ser puras. O que isso significa? Uma função não deveria gerar efeitos colaterais. Dada uma quantidade de parâmetros e os parâmetros recebidos, o retorno é sempre o mesmo.
Então, não vamos manipular esses estados dentro da função. Cada função recebe o estado como parâmetro e retorna um novo estado. Esse é o conceito que devemos ter em mente durante a execução deste código.
Criação do estado inicial
Vamos começar criando nosso estado com let estado que é o estado da aplicação. Ele vai receber um objeto.
Podemos dizer para o TypeScript qual é esse tipo do estado. Logo depois de declarar let estado, vamos acrescentar dois-pontos e tipá-lo como EstadoAplicacao.
script-crud.ts:
let estado: EstadoAplicacao = {
}
O próprio VS Code, já indica um ponto de atenção. Ele sublinhou de vermelho a palavra estado, informando que esse estado está faltando tarefas e tarefasSelecionadas. Vamos adicionar essas propriedades que estão faltando.
Neste ponto, podemos pegar as tarefas do script-crud.js. Há um exemplo entre as linhas 16 e 29. Vamos copiar só o array de tarefas e colá-lo após escrever tarefas:.
E a tarefaSelecionada? Se pressionamos "Ctrl + Espaço", o VS Code já até sugere a propriedade tarefaSelecionada. No entanto, no momento inicial da aplicação, não temos tarefa selecionada.
Então, neste primeiro instante, tarefaSelecionada é null.
let estado: EstadoAplicacao = {
tarefas: [
{
descricao: 'Tarefa concluída',
concluida: true
},
{
descricao: 'Tarefa pendente 1',
concluida: false
},
{
descricao: 'Tarefa pendente 2',
concluida: false
}
],
tarefaSelecionada: null
}
Mas o VS Code já reclama que nulo não combina com o tipo desse estado, pois espera-se uma Tarefa. Vamos ter que ser um pouco mais flexíveis. Na definição do EstadoAplicacao, vamos dizer que a tarefaSelecionada pode ser uma Tarefa ou null.
interface EstadoAplicacao {
tarefas: Tarefa[]
tarefaSelecionada: Tarefa | null
}
Agora estamos um pouco mais flexíveis, até porque isso faz sentido. A tarefa pode existir, pois podemos ter selecionado uma tarefa. Mas também podemos não ter nenhuma tarefa selecionada.
Funções puras
Agora que temos a base pronta, podemos escalar e começar a escrever as funções. Um detalhe sobre as funções: elas serão puras, ou seja, dados os mesmos parâmetros recebidos, o retorno será sempre o mesmo - tomando cuidado para não gerar efeito colateral.
Se você está se perguntando: "O que é esse efeito colateral? Do que vocês estão falando?" Parece nome de filme, não é?
Vamos no script-crud.js para procurar uma função. Na linha 48, temos uma função chamada removerTarefas. Ela recebe o parâmetro somenteConcluidas, que talvez seja um booleano, mas, como é JavaScript, não temos certeza.
script-crud.js:
const removerTarefas = (somenteConcluidas) => {
const seletor = somenteConcluidas ? '.app__section-task-list-item-complete' : '.app__section-task-list-item'
document.querySelectorAll(seletor).forEach((element) => {
element.remove();
});
tarefas = somenteConcluidas ? tarefas.filter(t => !t.concluida) : []
}
E o que ela faz? Ela tem uma lógica que define qual seletor ela vai aplicar. Pega esse seletor, deleta todos os elementos e, depois, aplica um filtro. Vamos fazer um "Ctrl + B" para colapsar o painel do explorador e deixar o código bem evidente.
Em seguida, ele verifica: se é somenteConcluidas, ele aplica um filtro na variável tarefas e a modifica. Caso contrário, ele coloca um array vazio.
A variável tarefas da linha 54, que está recebendo esse valor, é a mesma que foi definida anteriormente na linha 16 em let tarefas. Isso é um efeito colateral.
Temos uma variável definida na linha 16 que está sendo manipulada na linha 54 e, muito provavelmente, outros lugares diferentes da aplicação vão gerar efeitos colaterais nessas tarefas. Nós não queremos isso.
O que desejamos é que a função receba essas tarefas por parâmetro e retorne um novo estado.
Esse conceito é chamado de função pura: dada a entrada que ela recebe, ela sempre retorna a mesma coisa. Se esses parâmetros são os mesmos, ela vai retornar sempre os mesmos valores.
Agora que temos o estado iniciado, podemos começar a construir essas funções puras, dando pequenos passos de maneira gradual. Até a próxima.