Com a estrutura montada, vamos começar criando no styled o input e também o input de máscara, que usamos no telefone e usaremos também para o CEP.
import styled from "styled-components/native";
import Constants from "expo-constants";
import { TextInputMask } from "react-native-masked-text";
const statusBarHeight = Constants.statusBarHeight;
export const Container = styled.ScrollView`
flex: 1;
background-color: ${({ theme }) => theme.colors.backgroundLight};
padding-top: ${statusBarHeight}px;
`;
export const InputContainer = styled.View`
width: 90%;
height: 50px;
border: 1px solid ${({ theme }) => theme.colors.borderColor};
background-color: ${({ theme }) => theme.colors.background};
border-radius: 5px;
margin: 0 auto;
margin-top: 20px;
padding-left: 10px;
`;
export const Input = styled.TextInput`
flex: 1;
font-size: 18px;
color: ${({ theme }) => theme.colors.primaryText};
`;
export const InputMask = styled(TextInputMask)`
flex: 1;
font-size: 18px;
color: ${({ theme }) => theme.colors.primaryText};
`;
Agora a gente pode começar a criar eles lá no index os inputs, e ver a sua estrutura se formando.
const AddAddress = () => {
return (
<Container>
<DefaultTitle fontSize={18} title="CADASTRAR ENDEREÇO" />
<InputContainer>
<InputMask
type={"zip-code"}
placeholder="Cep"
placeholderTextColor="#C0C0C1"
/>
</InputContainer>
<InputContainer>
<Input placeholder="Rua" placeholderTextColor="#C0C0C1" />
</InputContainer>
<InputContainer>
<Input
placeholder="Número"
placeholderTextColor="#C0C0C1"
keyboardType="number-pad"
/>
</InputContainer>
<InputContainer>
<Input placeholder="Complemento" placeholderTextColor="#C0C0C1" />
</InputContainer>
<InputContainer>
<Input placeholder="Bairro" placeholderTextColor="#C0C0C1" />
</InputContainer>
<InputContainer>
<Input placeholder="Cidade" placeholderTextColor="#C0C0C1" />
</InputContainer>
<InputContainer>
<Input
placeholder="Estado"
placeholderTextColor="#C0C0C1"
maxLength={2}
/>
</InputContainer>
</Container>
);
};
Por enquanto a estrutura está crua, os inputs vão funcionar de forma melhor, vamos colocar o botão para poder finalizar ela
<Container>
<DefaultTitle fontSize={18} title="CADASTRAR ENDEREÇO" />
<InputContainer>
<InputMask
type={"zip-code"}
placeholder="Cep"
placeholderTextColor="#C0C0C1"
/>
</InputContainer>
<InputContainer>
<Input placeholder="Rua" placeholderTextColor="#C0C0C1" />
</InputContainer>
<InputContainer>
<Input
placeholder="Número"
placeholderTextColor="#C0C0C1"
keyboardType="number-pad"
/>
</InputContainer>
<InputContainer>
<Input placeholder="Complemento" placeholderTextColor="#C0C0C1" />
</InputContainer>
<InputContainer>
<Input placeholder="Bairro" placeholderTextColor="#C0C0C1" />
</InputContainer>
<InputContainer>
<Input placeholder="Cidade" placeholderTextColor="#C0C0C1" />
</InputContainer>
<InputContainer>
<Input
placeholder="Estado"
placeholderTextColor="#C0C0C1"
maxLength={2}
/>
</InputContainer>
<DefaultButton
buttonText="Cadastrar Endereço"
buttonHandle={() => {}}
buttonType="primary"
marginVertical={30}
/>
</Container>
Nesse form, já vamos deixar a sua lógica base funcionando, ao terminar de preencher o input e ir para o próximo campo, nós vamos puxar de uma api a rua e todas as outras informações, para facilitar a vida do usuário.
Para fazer isso, primeiro nós vamos criar os estados para todo o form, para que a gente possa manipular os campos e seus valores.
const AddAddress = () => {
const [fields, setFields] = useState({
cep: "",
street: "",
number: "",
complement: "",
district: "",
city: "",
state: "",
});
Agora a gente vai alterar isso de input em input, começando pelo mais diferente, que é o input mask. Nós vamos usar o replace para deixar apenas os números quando formos cetar, pois a API que vamos usar para pegar as informações via cep precisa que a gente envie só números, e ela salva números com o “-”.
<InputContainer>
<InputMask
type={"zip-code"}
placeholder="Cep"
value={fields.cep}
onChangeText={(value) =>
setFields({ ...fields, cep: value.replace(/[^0-9]/g, "") })
}
placeholderTextColor="#C0C0C1"
/>
</InputContainer>
Agora podemos continuar para os demais inputs.
<InputContainer>
<Input
placeholder="Rua"
placeholderTextColor="#C0C0C1"
value={fields.street}
onChangeText={(val) => {
setFields({ ...fields, street: val });
}}
/>
</InputContainer>
<InputContainer>
<Input
placeholder="Número"
placeholderTextColor="#C0C0C1"
keyboardType="number-pad"
value={fields.number}
onChangeText={(val) => {
setFields({ ...fields, number: val });
}}
/>
</InputContainer>
<InputContainer>
<Input
placeholder="Complemento"
placeholderTextColor="#C0C0C1"
value={fields.complement}
onChangeText={(val) => {
setFields({ ...fields, complement: val });
}}
/>
</InputContainer>
<InputContainer>
<Input
placeholder="Bairro"
placeholderTextColor="#C0C0C1"
value={fields.district}
onChangeText={(val) => {
setFields({ ...fields, district: val });
}}
/>
</InputContainer>
<InputContainer>
<Input
placeholder="Cidade"
placeholderTextColor="#C0C0C1"
value={fields.city}
onChangeText={(val) => {
setFields({ ...fields, city: val });
}}
/>
</InputContainer>
<InputContainer>
<Input
placeholder="Estado"
placeholderTextColor="#C0C0C1"
maxLength={2}
value={fields.state}
onChangeText={(val) => {
setFields({ ...fields, state: val });
}}
/>
</InputContainer>
Agora a gente já consegue utilizar a máscara, podemos utilizar a API, vamos criar a função pegando a api do seguinte site: https://viacep.com.br
const handleGetAddress = async () => {
const res = await axios.get(`https://viacep.com.br/ws/${fields.cep}/json/`);
console.log(res);
};
Nós iremos usar uma coisa chamada “OnBlur” que é um evento chamado quando saímos do input, e ao sair do cep vamos chamar essa função, que por enquanto vai apenas mostrar no console a sua resposta.
<InputContainer>
<InputMask
type={"zip-code"}
placeholder="Cep"
placeholderTextColor="#C0C0C1"
value={fields.cep}
onChangeText={(value) =>
setFields({ ...fields, cep: value.replace(/[^0-9]/g, "") })
}
onBlur={() => {
handleGetAddress();
}}
/>
</InputContainer>
Podemos ver na resposta que ele nos trás o endereço completo, vamos usar isso para preencher todas as informações que podemos do form, facilitando a vida do usuário. Vamos desestruturar o data para facilitar a nossa vida na hora de setar.
const handleGetAddress = async () => {
const { data } = await axios.get(`https://viacep.com.br/ws/${fields.cep}/json/`);
setFields({
...fields,
street: data.logradouro,
state: data.uf,
city: data.localidade,
district: data.bairro,
});
};
Com isso nós já podemos testar, ao sair do campo de cep, a gente vai tem tudo preenchido, menos o de número e complemento, pois o usuário precisa informar.
Agora podemos prosseguir, já que criamos o form.