Consultando o estado da sua aplicação através de seletores

Durante o desenvolvimento de uma aplicação que utiliza os estados como a principal forma de armazenamento de dados, frequentemente, nós os consultamos para retornar as informações desejadas. Só que em muitos casos, quando não se definem seletores, a lógica dessas consultas acaba ficando espalhada em diversos locais como componentes, containers, actions, etc…

De cara, já conseguimos visualizar que este modo pode nos trazer alguns problemas no futuro como repetição de código, falta de reaproveitamento e legibilidade.

Logo, a função dos seletores é abstrair esta lógica de seleção (bem claro não?). A grosso modo, eles irão funcionar como queries de um banco de dados. E, de fato, nosso estado funciona como um. Pensar dessa forma vai te ajudar a tomar melhores decisões quando você for organizá-lo evitando principalmente a duplicidade de informações.

Um exemplo bem simples é quando temos um estado que armazena dados de uma loja e queremos pegar as informações do produto selecionado ou dos produtos de uma determinada categoria.

const state = {
selectedProductId: 4,
productsById: {
1: { name: "Livro A", price: "60", categoryId: 2 },
2: { name: "Livro B", price: "50", categoryId: 2 },
3: { name: "Travesseiro", price: "200", categoryId: 1 },
4: { name: "Liquidificador", price: "150", categoryId: 3 }
},
categoriesById: {
1: { name: "Enxoval" },
2: { name: "Livro" },
3: { name: "Eletrodoméstico" }
}
}
const getSelectedProduct = state => {
return state.productsById[state.selectedProductId]
}
const getProductsByCategory = (state, categoryId) => {
return state.productsById.filter(product => product.categoryId === categoryId)
}

Utilizando seletores como mostrado acima, temos a lógica centralizada em apenas um lugar e de forma clara.

Eu gosto de colocar os seletores em um arquivo chamado selectors.js. Onde você vai colocar depende de como a app foi estruturada e o que faz mais sentido pro seu time.

Um outro ganho também que você pode ter ao se trabalhar com seletores, é o de cachear resultados. Assim, seu estado não será acessado a cada renderização. Uma biblioteca bem legal pra isso é o reselect, vale a pena dar uma olhadinha nela e ver se ela se encaixa no seu projeto.

E você? Como faz? Utiliza seletores ou pensa de uma forma diferente?