Exibindo os resultados do trabalho de um thunk em um componente no Redux
Na lição anterior, enviamos uma requisição POST
usando o thunk addProduct. Vamos agora
exibir os resultados do seu trabalho no componente.
Vamos abrir nosso aplicativo de produtos, e nele
o arquivo NewProductForm.jsx, já que este
componente é responsável por adicionar um novo
produto. Vamos olhar as linhas de importação.
Vamos substituir a importação da action productAdded pela
importação do thunk addProduct:
import { addProduct } from './productsSlice'
Agora, como não estamos rastreando o status
'pending' da requisição no slice, vamos fazer com que
o usuário possa clicar no botão de salvar
produto apenas uma vez, pois
não queremos requisições repetidas idênticas.
Para isso, vamos criar outro estado local:
const [requestStatus, setRequestStatus] = useState('idle')
Em seguida, após os manipuladores e antes da função
onSaveProductClick, vamos escrever um código que
verifica se todos os campos do formulário estão preenchidos
e se o status da requisição está como 'idle':
const canBeSaved =
[name, desc, price, amount, sellerId].every(Boolean) &&
requestStatus === 'idle'
Depois, vamos alterar o código para onSaveProductClick. Em primeiro lugar,
será uma função assíncrona e será executada
se a condição acima for verdadeira:
const onSaveProductClick = async () => {
if (canBeSaved) {}
}
Embora não rastreemos o status
'rejected' no slice, ainda podemos exibir no
console o erro, para isso usaremos a
estrutura try-catch.
Também adicionaremos um finally,
para após a execução da requisição, redefinir
o estado local para 'idle':
const onSaveProductClick = async () => {
if (canBeSaved) {
try {
} catch (err) {
console.error('Erro ao salvar produto: ', err)
} finally {
setRequestStatus('idle')
}
}
}
Já tratamos dos blocos catch e finally, vamos
escrever o código para o bloco try. Aqui vamos definir o status
local como 'in pogress', até recebermos
alguma resposta como resultado do trabalho do thunk,
depois enviaremos nosso thunk addProduct. Usar
a estrutura try-catch dependendo
do tipo de resposta será possível com a função do RTK unwrap,
que ele adiciona à promise retornada.
Então, se a requisição for bem-sucedida, definimos
os estados locais para seus estados iniciais. O código
completo para onSaveProductClick ficará assim:
const onSaveProductClick = async () => {
if (canBeSaved) {
try {
setRequestStatus('in progress')
await dispatch(
addProduct({ name, desc, price, amount, seller: sellerId })).unwrap()
setName('')
setDesc('')
setPrice(0)
setAmount(0)
setSellerId('')
} catch (err) {
console.error('Erro ao salvar produto: ', err)
} finally {
setRequestStatus('idle')
}
}
}
Vamos executar nosso aplicativo e tentar adicionar um novo produto. Como você pode ver, em caso de sucesso da requisição, os campos são limpos e o novo produto é adicionado à lista de produtos. Também abra no navegador o Redux DevTools e navegue pelas suas abas, veja as actions e como seu estado muda.
Abra seu aplicativo de estudantes.
Abra nele o arquivo NewStudentForm.jsx.
Adicione outro estado local requestStatus,
e defina-o inicialmente como 'idle'.
Consultando os materiais da lição, crie
a variável canBeSaved, com a qual
o botão de salvar novos dados do estudante irá
funcionar/não funcionar, dependendo do valor
de requestStatus e do preenchimento dos campos.
Escreva o código assíncrono para onSaveStudentClick,
que irá alterar o valor de requestStatus
conforme a situação, enviar o thunk addProduct
com os dados do novo estudante, limpar os campos
em caso de requisição bem-sucedida e exibir no
console o erro em caso de falha,
como mostrado na lição. Use para isso
a estrutura try-catch e a função do RTK
unwrap.
Execute seu aplicativo, adicione um novo estudante e certifique-se de que tudo funciona.