React Native hooks useState - setState array dont work - react-native

When i try to set state from API, i have response.data but setState dont work.
const [items, setItems] = useState([]);
useEffect(() => {
cargarItems();
}, [])
const cargarItems = async () => {
const res = await fetch('http://localhost:4000/api/items');
const data= await res.json();
setItems(data);
console.log(data);
console.log(items); }
Also try:
await axios
.get('http://localhost:4000/api/items')
.then((res) => {
console.log(typeof res.data);
setItems(res.data);
})
.catch((err) => {
console.log(err);
});
console.log(items);
And allways i get:
I have the response but the state is not updated.
Thanks in advance

Related

How to pass the parameter to another screen using axios?

I'm doing the verification of the phone number, and I have to pass the phone number to the other checkCode.js component.
I have seen examples that pass it navigate() as a pramas, but how can I receive it in another component.
register.js
const SignUp = ({ navigation }) => {
const [phoneNumber, setPhoneNumber] = useState('');
let register = "https://app.herokuapp.com/api/v1/auth/register"
let sendVerification = "https://app.herokuapp.com/api/v1/auth/sendVerification-otp"
const signUp = () => {
const userParams = {
phone: phoneNumber,
};
const requestOne = axios.post(register, userParams)
const requestTwo = axios.post(sendVerification, userParams)
axios
.all([requestOne, requestTwo], userParams)
.then(axios.spread((...responses) => {
navigation.navigate('CodeVerification')
}))
.catch((err) => {
console.log('the error:', err.message);
})
}
checkCode.js
export default function CodeVerification({navigation}) {
//need phoneNumber param in this component
const [code, setCode] = useState('');
const confirm = () =>{
const userParams = {
phone: "+11111111",
code:code,
};
axios
.post('https://app.herokuapp.com/api/v1/auth/sendVerification-otp', userParams)
.then((response) =>{
console.log('response', response.data);
navigation.navigate('Welcome')
})
.catch((error) => {
console.log('the error:', error.message);
});
};
How can I pass it?
This might help
register.js
const SignUp = ({ navigation }) => {
// existing code remains the same
const signUp = () => {
....
axios
.all([requestOne, requestTwo], userParams)
.then(
axios.spread((...responses) => {
// send params like this
navigation.navigate("CodeVerification", {phone: phoneNumber});
})
)
.catch((err) => {
console.log("the error:", err.message);
});
};
};
checkCode.js
export default function CodeVerification({ route, navigation }) {
// get phoneNumber from props
const {phone} = route.params; // UPDATED this line
const [code, setCode] = useState("");
....
}
You can use Context Api
Context api is commonly used for transferring data to another component.

React Native -how to clean use effect hook

I'm new to react native and currently trying to make an app with firebase v9 for practice. I'm kinda stuck with the hook issue, as it says:
[Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.]
This is the Login Component:
const LoginScreen = ( {navigation}) => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [storeKey, setStoreKey] = useState([]);
const [userName, setName] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [image, setImage] = useState(null);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (authUser) => {
if(authUser){
AfterLogin();
}
});
return unsubscribe;
}, []);
const signInUser = () => {
signInWithEmailAndPassword(auth, email, password)
.then(async (re) => {
//setIsSignedIn(true);
AfterLogin();
})
.catch((error) => {
console.error(error);
})
}
const AfterLogin = () => {
if(!storeKey || !userName || !image){
getData(setStoreKey, setName, setIsLoading, setImage);
}
navigation.replace('Drawer', {
storeKey: storeKey,
userName: userName,
image: image,
});
}
And this is the getData Function:
const getData = async(setStoreKey, setName, setIsLoading, setImage) => {
const auth = getAuth();
const user = auth.currentUser;
if(user !== null){
const email = user.email;
const UserInfo = await getDoc(doc(db, 'users', email));
if(UserInfo.exists()){
setStoreKey(UserInfo.data().storeKey)
setName(UserInfo.data().name);
setIsLoading(false)
setImage(UserInfo.data().postImage)
}
else{
console.log('None')
}
return
}
}
I guess the problem is happening in the useEffect in Login, but I don't know how to solve this :S
EDIT: I think the problem is from getData function. When I comment out getData function in AfterLogin, it works fine without error :S
but I don't know how it causes error.
Is it because it's async function?
Try this
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (authUser) => {
if(authUser){
AfterLogin();
}
});
return () => {
unsubscribe();
}
}, []);

how do I make an array in state - reactnative

I'm taking the images I uploaded to cloud storage, but the problem is the variable is not an array, so it is only storing just one url. How do I make variables with state array?
My code:
const reference = storage().ref('images');
const [imageUrl, setImageUrl] = useState();
const refer = storage().ref('images');
useEffect(() => {
try {
listFilesAndDirectories(reference).then(() => {
console.log('Finished listing');
});
refer.list().then(result => {
result.items.forEach(element => {
element.getDownloadURL().then(downloadUrl => {
setImageUrl(downloadUrl)
console.log(imageUrl)
console.log("=================")
}).catch(error =>{
alert(error)
})
})
})
} catch (error) {
alert(error);
}
}, []);
Is that what you are looking for?
const [items, setItems] = useState([]);
const handleStateChange = () => {
setItems(state => [...state, 'someNewItem']);
}
With useCallback
const handleStateChange = useCallback(function () {
setItems(state => [...state, 'someNewItem']);
}, [])

Getting variable from AsyncStorage and putting into Axios

I have been trying to get a variable from AsyncStorage and then put it into an Axios get request. The problem is that the variable is not updating to the data that is retrieved from AsyncStorage. How do I make it do that?
Here is my code:
const [sku, setSku] = useState('')
const STORAGE_KEY_SKU = '#save_sku'
const readSku = async () => {
try {
const selectedSku = await AsyncStorage.getItem(STORAGE_KEY_SKU)
if (selectedSku !== null) {
setSku(selectedSku)
}
} catch (e) {
alert('Failed to fetch the data from storage')
}
}
useEffect(() => {
readSku()
}, []);
useEffect(() => {
Axios.get(`https://api.vexdb.io/v1/get_matches?sku=${sku}`)
.then(({ data }) => {
//console.log("defaultApp -> data", data)
setData(data.result)
})
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, []);
Im trying to put get the sku variable from the state from AsyncStorage, but the ${sku} in the axios get request link is not working, the sku is blank in that statement.
Please help, thanks!
useFocusEffect(() => {
readSku()
}, []);
const STORAGE_KEY_SKU = '#save_sku'
// to get the session username from localstorage
const readSku = async () => {
try {
const selectedSku = await AsyncStorage.getItem(STORAGE_KEY_SKU)
if (selectedSku !== null) {
setSku(selectedSku)
}
} catch (e) {
console.log(e);
}
}
const setSku = async (selectedSku) => {
Axios.get(`https://api.vexdb.io/v1/get_matches?sku=${selectedSku}`)
.then(({ data }) => {
//console.log("defaultApp -> data", data)
setData(data.result)
})
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}

How to assign value to global variable in fetch method in react native?

I am creating a react native app and I'm getting data from an API. I need to assign specific data into a global variable. That means my API return JSON data like {user_Id:"1' user_name:'abc' user_email:'abc#gmail.con'}. I need to assign user_Id into a global variable to access that in all of my screens.
This is what I tried;
componentDidMount() {
const arrFinal = [];
const {userDel} = this.state;
fetch('my API url')
.then(response => response.json())
.then(responseJson => {
// console.warn(responseJson);
arrFinal.push(responseJson);
arrFinal.map((item, index) => {
global.UserID = item.user_Id
})
.catch(error => {
console.error(error);
});
console.error(global.UserID)
}
But here nothing will print on console. How can I fix this problem?
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
componentDidMount() {
const arrFinal = [];
const {userDel} = this.state;
fetch('my API url')
.then(response => response.json())
.then(responseJson => {
// console.warn(responseJson);
arrFinal.push(responseJson);
arrFinal.map((item, index) => {
global.UserID = item.user_Id
console.error(global.UserID)
})
.catch(error => {
console.error(error);
});
// console.error(global.UserID)
}
or :
async componentDidMount() {
const arrFinal = [];
const { userDel } = this.state;
const response = await fetch('my API url');
const responseJson = await response.json();
// console.warn(responseJson);
arrFinal.push(responseJson);
arrFinal.map((item, index) => {
global.UserID = item.user_Id;
console.error(global.UserID);
});
console.error(global.UserID);
}