Integrating class based Axios request to the hook based code - reactjs

How can I integrate this class based Axios request to the other hook based code that gets data from a Json file? Basically I want to replace data source LOCATIONS with the Axios get request. Thanks.
componentDidMount () {
axios.get('http://192.168.2.94:3000/list-places').then(res => {
this.setState({
posts: res.data
})
})
}
import { LOCATIONS } from '../data/data'
const HomeScreen = props => {
const renderGridItem = itemData => {
return (
<CategoryGridTile
image={itemData.item.image}
title={itemData.item.title}
onSelect={() => {
props.navigation.navigate({
routeName: 'Categories',
params: {
locationId: itemData.item.id
}
})
}}
/>
)
}
return (
<FlatList
keyExtractor={(item, index) => item.id}
data={LOCATIONS}
renderItem={renderGridItem}
/>
)
}

You just want to get LOCATIONS data from the API? Something like this should work (code is untested)
const HomeScreen = props => {
const [locations, setLocations] = useState(undefined);
useEffect(() => {
async function getLocations() {
const { data } = await axios.get('http://192.168.2.94:3000/list-places');
setLocations(data);
}
getLocations();
}, []);
// ...
return (
<>
{locations && (
<FlatList
keyExtractor={(item, index) => item.id}
data={locations}
renderItem={renderGridItem}
/>
)}
</>
);
};

Related

Flat list not being rendered in react native

In my React native page
Im navigating from one page to another page with parameters
so those parameters has id
which will be used to fetch data from endpoint and display that in flat list
function Assessments ({route,navigation}) {
useEffect(()=>{
fetchData(file)
},[]);
const { file } = route.params;
const [data,setData] = useState([]);
file consists of route params(Id)
and fetchdata function triggers that function with the id and fetches data
const fetchData = async (file) => {
axios.get(`endpoint`)
.then(function (response) {
console.log(response.data)
setData(response.data)
})
.catch(function (error) {
console.log(error);
})
}
and im returning this
return (
<View>
<Text>okay</Text>
<FlatList
flexGrow= {0}
minHeight= '20%'
maxHeight='80%'
data={data}
renderItem={showdata}>
</FlatList>
</View>
)
and renderitem is
const showdata = ({item}) => {
<View>
sdfdsfsdf
</View>
}
but that part isnt even being rendered
not sure where is the issue !
console.log()
{
"id": 19,
"name": "test1",
}
this is how the data from the endpoint is
Your showdata is not returning anything. Please add return to it like this.
Here is the full code.
function Assessments ({route, navigation}) {
const { file } = route.params;
const [data, setData] = useState([]);
useEffect(()=>{
fetchData(file)
},[]);
const fetchData = async (file) => {
axios.get(`endpoint`)
.then(function (response) {
console.log(response.data)
setData(response.data)
})
.catch(function (error) {
console.log(error);
})
}
const showdata = ({ item }) => {
//Add return here
return (
<View>
<Text>
sdfdsfsdf
</Text>
</View>
)
}
return (
<View>
<Text>okay</Text>
<FlatList
//Put all the style within style prop
style={{flexGrow: 0, minHeight: '20%', maxHeight: '80%'}}
data={data}
renderItem={showdata}
>
</FlatList>
</View>
)
}

React variable value not replaced in api call

I am trying to use UseParam to get the id, i am trying to place it inside of my API request however when i console.log it the actual value doesn't go inside rather the text itself.
vesselComponents.js :
function VesselComponents() {
const { id } = useParams();
const api = async () => {
try {
const res = await axios.get(
// here
`http://127.0.0.1:8000/api/maintenance/${id}`
);
return res.data;
} catch (error) {
console.log(error);
}
};
console.log(api);
const { components, error, loading } = useSelector(
(state) => state.components
);
const dispatch = useDispatch();
useEffect(() => {
fetchComponents()(dispatch);
}, [dispatch]);
const getTreeItemsFromData = (treeItems) => {
return treeItems.map((treeItemData) => {
let children = undefined;
if (treeItemData.children && treeItemData.children.length > 0) {
children = getTreeItemsFromData(treeItemData.children);
}
return (
<TreeItem
component={Link}
to={`./info/${treeItemData.id}`}
key={treeItemData.id}
nodeId={String(treeItemData.id)}
label={treeItemData.name}
children={children}
/>
);
});
};
const DataTreeView = ({ treeItems }) => {
return (
<TreeView
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
>
{getTreeItemsFromData(treeItems)}
</TreeView>
);
};
return (
<div className="components-container">
<div className="components-items">
<DataTreeView treeItems={components} />
</div>
<div className="component-detail">
<Outlet />
</div>
</div>
);
}
export default VesselComponents;
This is how the console.log look like :
async () => {
try {
const res = await axios__WEBPACK_IMPORTED_MODULE_3___default().get( // here
`http://127.0.0.1:8000/api/maintenance/${id}`);
return res.data;
} catch (err…
Also if i wanted to make this call rather in my slice how would i go about exporting this specific ID that changes so i can use it there.
This is because you actually log the function, not the return value.
I suppose you want to fetch the maintenance id as the component mounts. I advice you to use useEffect for this case.
import { useEffect, useState } from 'react'; // above the component's class declaration
// and inside your component
const [api, setApi] = useState(null); // null by default
useEffect(() => {
const fetchMaintenance = async () => {
try {
const res = await axios.get(
// here
`http://127.0.0.1:8000/api/maintenance/${id}`
);
return res.data;
} catch (error) {
throw Error(error);
}
});
};
fetchMaintenance()
.then((api) => {
setApi(api);
})
.catch((error) => {
console.log(error);
});
}, []);
And by that you can use the value of api anywhere you like.
For example to log it
useEffect(() => {
console.log(api);
}, [api]);
or to render it on your view
return (
return (
<div className="components-container">
{JSON.stringify(api)}
<div className="components-items">
<DataTreeView treeItems={components} />
</div>
<div className="component-detail">
<Outlet />
</div>
</div>
);
}

Invalid use of Hooks when using onPress to call a function

I ran into this issue of Invalid hook call. The AltIconButton is a component that I place in the export default function with redirect={GoogleLogin}
Here is my login.js snippet:
const AltIconButton = (props) => {
console.log(props.name);
return (
<TouchableOpacity activeOpacity={0.5} onPress={props.redirect}>
<MaterialCommunityIcons
style={{
marginHorizontal: 15,
}}
name={props.name}
size={48}
color="white"
/>
</TouchableOpacity>
);
};
Then this is my google_login:
function GoogleLogin() {
const navigation = useNavigation();
const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
expoClientId: Constants.manifest.extra.google.WEB_CLIENT_ID,
});
useEffect(() => {
if (response?.type === "success") {
const { id_token } = response.params;
const credential = Firebase.auth.GoogleAuthProvider.credential(id_token);
Firebase.auth()
.signInWithCredential(credential)
.then(() => {
navigation.replace("Home");
});
}
}, [response]);
return;
}
EDIT:
This is another snippet of where I implement my AltIconButton Component
<View style={styles.bottomBody}>
<AltIconButton name="facebook" redirect={FBLogin}></AltIconButton>
<AltIconButton name="google"redirect={GoogleLogin}></AltIconButton>
</View>
By changing the JS function into its own component solve the problem.
For example:
function GoogleLogin() {
const navigation = useNavigation();
const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
expoClientId: Constants.manifest.extra.google.WEB_CLIENT_ID,
});
useEffect(() => {
if (response?.type === "success") {
const { id_token } = response.params;
const credential = Firebase.auth.GoogleAuthProvider.credential(id_token);
Firebase.auth()
.signInWithCredential(credential)
.then(() => {
navigation.replace("Home");
});
}
}, [response]);
return (
<TouchableOpacity
disabled={!request}
activeOpacity={0.5}
onPress={() => promptAsync()}
/>
);
}

How to implement infinite list using React Query in react native with Flatlist

Here is my code:
import React, {useState} from 'react';
import {useQuery, useInfiniteQuery} from 'react-query';
import {getMeetup} from '../../api/methods/getMeetups';
export default function MyFunction(props) {
const [next, setNext] = useState('');
const fetchData = async ({pageParam = ''}) => {
const response = await getMeetup( pageParam);
console.log('API RESP', response);
return response;
};
const {data, isLoading, fetchNextPage} = useInfiniteQuery(
'myData',
fetchData,
{
getNextPageParam: (lastPage, pages) => lastPage?.next?._id,
},
);
console.log('RQUERY CHECK', data);
const getMore = () => {
console.log('data end', data?.pages[0]?.next?._id);
fetchNextPage({pageParam: data?.pages[0]?.next?._id});
};
const flattenData = data?.pages
? data?.pages?.flatMap((page) => [...page.Docs])
: [];
return (
<View>
<FlatList
style={{
marginBottom: verticalScale(40),
paddingHorizontal: scale(15),
}}
data={flattenData}
keyExtractor={(item) => item._id}
renderItem={({item, index}) => {
return <ListItem data={item} index={index} />;
}}
onEndReachedThreshold={0.1}
onEndReached={getMore}
/>
</View>
);
}
The problem i am facing is when the page loads the api calls one by one with unique next ids or page param. What i was trying to implement is , when user reaches the end of the page (onEndReached) the data needs to be fetched with a new page param.
getNextPageParam return the value for the next page. So you don't need pass pageParam in fetchNextPage unless you want overwrite, for any reason, the next page value.
You can add a hasNextPage validation for unnecessary requests.
const {data, isLoading, hasNextPage, fetchNextPage} = useInfiniteQuery( /* your code */ )
const getMore = () => {
if(hasNextPage)
fetchNextPage();
};

How to return JSX from this function React/React-native

I have a function from where I want to return JSX. I´m new to React, I tried this:
history is array of objects and I want to return text from it and display it.
renderCard = () => {
const db = firebase.firestore();
db.collection("users")
.doc(firebase.auth().currentUser.uid)
.collection("userRequestDeposit")
.get()
.then(snapshot => {
let history = snapshot.docs.map(doc => {
const data = doc.data().request;
return { ...data };
});
history.forEach(elem => {
return (
<View>
<Text>{elem.data}</Text>
</View>
);
});
});
};
So this is a nice case study for how to use React.
You want to fetch this data when the component mounts. When you have the data, you will update the component's state. You can then render the output from that state.
Here is how you could do this with your code:
import {useEffect, useState} from 'react';
const YourComponent = () => {
const [history, setHistory] = useState([]); // Store your data in this state
// this useEffect will run only once (when the component mounts).
useEffect(() => {
db.collection('users')
.doc(firebase.auth().currentUser.uid)
.collection('userRequestDeposit')
.get()
.then(snapshot => setHistory(snapshot.docs.map(doc => ({...doc.data().request}))));
}, []); // <-- the empty dependency array means it only runs on mount
// when history is updated, you can map over the array and render the output here
return history.map(item => (
<View key={item.id}>
<Text>{item.data}</Text>
</View>
));
};
or as a class component...
import {Component} from 'react';
class YourComponent extends Component {
state = {
history: [],
};
componentDidMount() {
db.collection('users')
.doc(firebase.auth().currentUser.uid)
.collection('userRequestDeposit')
.get()
.then(snapshot => {
this.setState({history: snapshot.docs.map(doc => ({...doc.data().request}))});
});
}
render() {
return history.map(item => (
<View key={item.id}>
<Text>{item.data}</Text>
</View>
));
}
}

Resources