Reputation: 51
I'm new to react native, so I apologize for errors in the code. First: I use Android Studio, VS Code, react native(expo) and sqlite(expo), supporting only android (I haven't programmed for ios yet).
I have a serious problem in my code and I have no idea how to start. The 'useEffect', to work, you have to save the file 2 times (ctrl+s in vs code). Don't just open the app.
THIS IS MY LOGIN PAGE login.js
import React, {useState,useEffect} from 'react';
import {View,Text,Pressable,Image,FlatList,ImageBackground,Alert} from 'react-native';
import {TextInput} from 'react-native-gesture-handler';
import fundoLogin from './styleLogin';
import Tb_user from '../../src/models/tb_user';
import Tb_veic_user from '../../src/models/tb_veic_user';
import db from "../../src/services/SQLiteDatabse";
import NetInfo from '@react-native-community/netinfo';
const printUser = (user) => {
console.log(`ID_user:${user.ID_user}, username:${user.username}, senha:${user.senha}, ID_empresa:${user.ID_empresa}, nome_empresa:${user.nome_empresa}, status_user:${user.status_user}`)
}
const printV = (v) => {
console.log(`ID_veic_uso:${v.ID_veic_uso}, username:${v.username}, placa:${v.placa}, atividade:${v.atividade}, data_inic:${v.data_inic}, km_inic:${v.km_inic}, data_final:${v.data_final}, km_final:${v.km_final}, obs:${v.obs}, integrado:${v.integrado}`)
}
function Login({ navigation, route }) {
const [username, setUsername] = useState("")
const [password, setPassword] = useState("")
const [errorLogin, setErrorLogin] = useState("")
const [users, setUsers] = useState([])
const [net, setNet] = useState("")
const [dadosVeic, setDadosVeic] = useState([])
const [info, setInfo] = useState([])
const findTbVeic = (id) => {
return new Promise((resolve, reject) => {
db.transaction((tx) => {
tx.executeSql(
"SELECT * FROM tb_veic_user WHERE integrado=0 AND km_final IS NOT NULL ;",
[],
//-----------------------
(_, { rows }) => {
if (rows.length > 0) {
resolve(rows._array)
}
else {
reject("Obj not found: id=" + id);
} // nenhum registro encontrado
},
(_, error) => reject(error) // erro interno em tx.executeSql
);
});
});
};
useEffect(() => {
NetInfo.fetch().then(state => {
setNet(state.isConnected)
});
if (net === true) {
findTbVeic()
.then(a => setDadosVeic(a))
.then( dadosVeic.map(item => {
// ENVIA DADOS PARA A API
fetch('url API', {
method: 'POST',
body: JSON.stringify({
username: item.username,
placa: item.placa,
atividade: item.atividade,
data_inic: item.data_inic,
km_inic: item.km_inic,
data_final: item.data_final,
km_final: item.km_final
}),
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
})
//ALTERA O 'INTEGRADO' == 1
Tb_veic_user.updateV( item.ID_veic_uso )
}))
}else{
console.log('sem conexao com a internet')
}
},[])
const importTbUser = () => {
// DADOS DA API SALVA EM CONST USERS
fetch('url API')
.then( res => res.json())
.then(
(dado) => {
setUsers(dado.data)
}
)
// INSERE, NO BANCO DE DADOS, OS DADOS DA API
const a = users.map((element) => {
Tb_user.create({ID_user:element.ID_user, username:element.username, senha:element.senha, ID_empresa:element.ID_empresa, nome_empresa:element.nome_empresa, status_user:element.status_user})
});
}
const login = () => {
// FAZER LOGIN
return new Promise((resolve, reject) => {
db.transaction(tx => {
tx.executeSql(
'SELECT ID_user, username, senha FROM tb_user WHERE username = ? and senha = ? LIMIT 1;',
[username, password],
//-----------------------
(_, { rows }) => {
if (rows.length > 0){
resolve(rows._array),
navigation.navigate('Veic', {
paramKey: username,
})
}else{
reject("Obj not found");
} // nenhum registro encontrado
},
(_, error) => reject(error) // Success
);
});
});
}
return (
<View style={fundoLogin.container}>
<ImageBackground
source={require('../../imagens/1.jpg')}
style={fundoLogin.imageFundo}
>
<Image
style={fundoLogin.imageLogo}
source={require('../../imagens/logo_cymi.png')}
/>
{net === true ?
<Image
style={{height:30,width:30}}
source={require('../../imagens/signal.png')}
/>
:
<Image
style={{height:30,width:30}}
source={require('../../imagens/no-signal.png')}
/>
}
<TextInput
style={fundoLogin.input}
placeholder='Digite seu email'
onChangeText={txtUsername => setUsername(txtUsername)}
value={username}
/>
<TextInput
style={fundoLogin.input}
placeholder='Digite sua senha'
secureTextEntry={true}
onChangeText={txtPassword => setPassword(txtPassword)}
value={password}
/>
{errorLogin === true
?
<View>
<Text style={fundoLogin.error}>email ou senha inválido</Text>
</View>
:
<View>
</View>
}
{(username === "" || password === "")
?
<Pressable
disabled={true}
style={fundoLogin.button}
>
<Text style={fundoLogin.textButton}>Login</Text>
</Pressable>
:
<Pressable
style={fundoLogin.button}
onPress={login}
>
<Text style={fundoLogin.textButton}>Login</Text>
</Pressable>
}
<Pressable
style={fundoLogin.button}
onPress={importTbUser}
>
<Text style={fundoLogin.textButton}>Importar</Text>
</Pressable>
<Pressable
style={fundoLogin.info}
onPress={navigation.navigate('Info')}
>
<Text style={fundoLogin.textInfo}>?</Text>
</Pressable>
</ImageBackground>
</View>
);
}
export default Login;
My app works like this: it starts on the login page (where there is a login button, import button and a company information button) and goes to another page to select a vehicle (this 'veic' page also has the same problem in useEffect). All components are working perfectly fine, I've checked all possible console.logs, and it's running fine. The only problem is that use effect doesn't work (on this page it has to be run 2x to refresh, on the 'veic' page it only does one thing, and the others don't). If anyone can tell me more, please. I don't even know if it's an error in my code or in Android Studio. Thank you in advance!!!
Upvotes: 0
Views: 732
Reputation: 1128
The problem is that you are not awaiting NetInfo.fetch()
.
Write the code under NetInfo.fetch()
in NetInfo.fetch().then(... your remaining useEffect code...)
.
Like this:
useEffect(() => {
NetInfo.fetch().then((state) => {
if (state.isConnected) {
findTbVeic()
.then(a => setDadosVeic(a))
.then( dadosVeic.map(item => {
// ENVIA DADOS PARA A API
fetch('url API', {
method: 'POST',
body: JSON.stringify({
username: item.username,
placa: item.placa,
atividade: item.atividade,
data_inic: item.data_inic,
km_inic: item.km_inic,
data_final: item.data_final,
km_final: item.km_final
}),
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
})
//ALTERA O 'INTEGRADO' == 1
Tb_veic_user.updateV( item.ID_veic_uso )
}))
}else{
console.log('sem conexao com a internet')
}
});
}, []);
For your other useEffect: The problem is that you can't change a state and than use that state in an useEffect drectly after. This is cause of the execution of the useEffect. It will only rerender when variables in the useEffect array change. For example:
const Test = () => {
const [test, setTest] = useState(false);
useEffect(() => {
fetchTest().then((data) => {
// lets say data.test is "true"
setTest(data.test); // set to true
// states in useEffect will keep the value they had when the useEffect started
// DONT:
console.log("test:", test): // --> "test: false"
// DO
console.log("test:", data.test): // --> "test: true"
});
}, []);
}
Upvotes: 1
Reputation: 51
I understood what Maximilan said, and on that login page it worked really well. But on the 'veic' page I'm not so lucky
useEffect(() => {
findByUserna( route.params.paramKey )
.then(
findByV(route.params.paramKey)
.then(
d => setDados(d)
),
console.log('use effect 1 ------>',dados)
)
.then(
dados.map(
item => setIDVeic(item.ID_veic_uso)
),
console.log('use effect 2 ------>',IDVeic)
)
},[])
When opening the screen, the consoles are empty, the variable is not saved, but when updating, it works, the variables are saved and shown in the console normally:
//The first time, console:
use effect 1 ------> Array []
use effect 2 ------> null
ENCONTRADO de tb_user o ID_user, username, nome_empresa ---> SORAIA
ENCONTRADO de tb_veic_user o ID_veic_uso onde kmf=null
//The second time, console:
use effect 1 ------> Array [
Object {
"ID_veic_uso": 4,
},
Object {
"ID_veic_uso": 7,
},
]
use effect 2 ------> 7
Upvotes: 0