How can I add sorting for API returning a JSON array? I'm new to Redux. I have installed the redux. Could someone tell me what's the best method to follow?
Thanks for your help.
import React, { useState, useEffect } from "react";
import Post from "../../Components/Post/Post";
import axios from "axios";
const HomePage = () => {
const [posts, setPosts] = useState("");
let config = { Authorization: "............." };
const url = "..........................";
useEffect(() => {
AllPosts();
}, []);
const AllPosts = () => {
axios
.get(`${url}`, { headers: config })
.then((response) => {
const allPosts = response.data.articles;
console.log(response);
setPosts(allPosts);
})
.catch((error) => console.error(`Error: ${error}`));
};
return (
<div>
<Post className="Posts" posts={posts} />
</div>
);
};
export default HomePage;
You don't have redux here. Do you need it?
If you want to sort result and save sorted results to state:
...
.then((response) => {
const allPosts = response.data.articles;
// sort the result here
const sortedPosts = allPosts.sort((a,b) =>
// comparer
);
setPosts(sortedPosts);
})
...
Related
I'm facing difficulty displaying data in React - Here is my code:
import Axios from 'axios';
import { useNavigate } from 'react-router';
export default function ProductCatalog() {
let navigate = useNavigate();
function addProduct() {
navigate('/adding')
}
const [products, setProducts] = useState([{}])
useEffect(() => {
const axiosProd = async () => {
const response = await Axios('http://localhost:3001/getProducts');
setProducts(response.data)
};
axiosProd();
}, []);
const useProducts = products.map((product)=>{
return <div>
<h1>{product.name}</h1>
</div>
})
return(
<>
<button className = "button" onClick={addProduct}>Add New Product</button>
<br></br>
{useProducts}
</>
)
}
I know data is coming in as JSON Objects as when i follow the link of http://localhost:3001/getProducts, I see my data. What am i doing wrong?
You should make a function then outside of the function call the use effect.
To do a get request using axios use axios.get(api)
For example:
// Get All Shoes
const getShoes = () => {
axios.get('/shoes')
.then(res => setShoes(res.data))
.catch(err => console.log(err));
}
Then
useEffect(() => {
getShoes();
}, [])
I've built a random photo displaying feature in react.
the console says that the response is valid and it works,
but the page breaks when I return data.
Where is the issue?
Thanks in advance!
import React from 'react'
import { useEffect, useState } from 'react'
import axios from 'axios'
function RandomPhoto() {
const url = `https://api.unsplash.com/photos/random/?client_id=${process.env.REACT_APP_UNSPLASH_KEY}`
const [data, setData] = useState()
const getPhoto = () => {
axios.get(url)
.then(response => {
setData(response.data)
console.log(response.data) // <------- works
})
.catch(error => {
console.log(error)
})
}
useEffect(() => {
getPhoto()
},[])
console.log("XX" + data) // <---------- doesn't work, and following return() neither
return (
<div>
<img href={data.urls.regular} alt={data.alt_description}/>
<p>Photo by {data.username} {data.name} from {data.location} - found on unsplash</p>
</div>
)
}
export default RandomPhoto
I modified your code a bit, and it's working. I made it as an async function and changed the path of JSON object keys.
Please note the location data sometimes returns as null. So you have to render it conditionally.
import React from 'react';
import { useEffect, useState } from 'react';
import axios from 'axios';
const RandomPhoto = () => {
const url = `https://api.unsplash.com/photos/random/?client_id=${process.env.REACT_APP_UNSPLASH_KEY}`;
const [imageData, setImageData] = useState('');
const getPhoto = async () => {
await axios
.get(url)
.then((response) => {
setImageData(response.data);
})
.catch((error) => {
console.log(error);
});
};
useEffect(() => {
getPhoto();
}, []);
return (
<div>
<p>Hello</p>
<img src={imageData.urls?.regular} />
<p>
Photo by {imageData?.user?.username} {imageData?.user?.name} from{' '}
{imageData?.location?.country} - found on unsplash
</p>
</div>
);
};
export default RandomPhoto;
I'm building MERN stack app wherein when logged in as Admin it will render all products in a table and when logged in as Not Admin it will render active products in cards.
I'm trying to do multiple fetch data in my Products.js page
//Products.js
import { Fragment, useEffect, useState, useContext } from "react";
import { Container, Table } from "react-bootstrap";
import ProductCard from "../components/ProductCard";
import UserContext from "../UserContext";
export default function Products() {
const { user } = useContext(UserContext);
const [userProducts, setUserProducts] = useState([]);
const [adminProducts, setAdminProducts] = useState([]);
// FETCH DATA
useEffect(() => {
fetchAdminProducts();
}, []);
useEffect(() => {
fetchUserProducts();
}, []);
const fetchAdminProducts = () => {
fetch("http://localhost:4000/products/all")
.then((res) => res.json())
.then((data) => {
setAdminProducts(data);
});
};
const fetchUserProducts = () => {
fetch("http://localhost:4000/products/")
.then((res) => res.json())
.then((data) => {
setUserProducts(data);
});
};
return (
<Fragment>
<Container>
{user.isAdmin === true ?
(...) :
(...)}
</Container>
</Fragment>
);
}
Am I doing it correctly?
How do I map Admin products in a table and User products in a card?
What is the best approach to fetch multiple data and render it conditionally when logged in?
Thanks for the help guys!
try to check the user role inside the useEffect
//Products.js
import { Fragment, useEffect, useState, useContext } from "react";
import { Container, Table } from "react-bootstrap";
import ProductCard from "../components/ProductCard";
import UserContext from "../UserContext";
export default function Products() {
const { user } = useContext(UserContext);
const [userProducts, setUserProducts] = useState([]);
const [adminProducts, setAdminProducts] = useState([]);
// FETCH DATA
useEffect(() => {
if(user.isAdmin){ // <-- check if is Admin
fetchAdminProducts();
} else{
fetchUserProducts();
}
}, []);
const fetchAdminProducts = () => {
fetch("http://localhost:4000/products/all")
.then((res) => res.json())
.then((data) => {
setProducts(data);
});
};
const fetchUserProducts = () => {
fetch("http://localhost:4000/products/")
.then((res) => res.json())
.then((data) => {
setProducts(data);
});
};
return (
<Fragment>
<Container>
{user.isAdmin === true ?
(...) :
(...)}
</Container>
</Fragment>
);
}
I would recommend having one function rather than 2 and also have like a state that will make that your useEffect go off.
const [state,setState]=useState(null);
const [products,setProducts]=useState([]);
const fetchProducts = () => {
if(user ==="Admin"){
fetch("http://localhost:4000/products/all")
.then((res) => res.json())
.then((data) => {
setProducts(data);
});
setState(true);
}
else{
fetch("http://localhost:4000/products/")
.then((res) => res.json())
.then((data) => {
setProducts(data);
});
setState(false);
}
};
usEffect(()=>{
fetchProducts();
},[state])
Then the return would look like that.
return (
{state ? <Table data=products> : <Card data=products>}
)
Would recommend create a seperate component that you call Table and Card that take in products. This will make your code more neat and easier to manage.
Hope this help.
I left the code below that I got my data from. More than one request is processed at the time of refreshing the page, the reason may be why, if you can help I would appreciate it. have a nice day.
import React, { useEffect, useState } from "react";
import axios from "axios"
import Cookies from "universal-cookie"
const Entry = React.createContext();
export const EntryProvider = ({ children }) => {
const [post, setPost] = useState();
const cookie = new Cookies()
const token = cookie.get("acsess_token")
const getAll = () => {
axios.defaults.headers.common['Authorization'] = token;
const entry = axios.get("/api/entry/entry", {
headers: {
"Authorization": token
}
})
.then((response) => {
const data = response.data.data
data.map(element => {
setPost(element)
});
setPost(data)
})
.catch((err) => { console.log(err) })
}
useEffect(() => {
getAll()
},[getAll])
return (
<Entry.Provider value={{post}}>
{children}
</Entry.Provider>
);
};
export const userEntry = () => {
return React.useContext(Entry);
};
Instead adding getAll in the array dependency, remove it
useEffect(() => {
getAll()
},[getAll])
Like this:
useEffect(() => {
getAll()
},[])
Why that?
Because the useEffect will be execute it every time the component renders and because of having getAll in the dependency array it will execute it again
I created a file Category.js
import React, { useState } from 'react'
export const CategoryData = (props) => {
const [Category, setCategory] = useState('')
fetch('https://www.amrutras.com/Category.php')
.then((response) => response.json())
.then((responseJson) => {
{
setCategory(responseJson)
// responseJson.map((item) => Alert.alert(item.Name))
}
// Showing response message coming from server after inserting records.
})
.catch((error) => {
console.error(error)
})
return Category
}
export default CategoryData
I want to use this Category const in my other component.
I tried to do that with
import CategoryData from '../consts/CategoryData'
and using this function in useEffect of another component. like this.
useEffect(() => {
console.log(CategoryData)
})
But it's not working.
You cannot use hooks directly within functions, unless they are custom hooks which you then cannot invoke inside other hooks but have to follow the rules of hooks to use them
You can restructure your code to implement CategoryData like a custom hook
export const useCategoryData = (props) => {
const [Category, setCategory] = useState('')
useEffect(() => {
fetch('https://www.amrutras.com/Category.php')
.then((response) => response.json())
.then((responseJson) => {
{
setCategory(responseJson)
// responseJson.map((item) => Alert.alert(item.Name))
}
// Showing response message coming from server after inserting records.
})
.catch((error) => {
console.error(error)
})
}, [])
return Category
}
export default useCategoryData;
Now you can use it in your component like
function App () {
const categoryData = useCategoryData();
...
}
SOLUTION2:
Another way to implement this is to not use custom hook but implement a normal function like
export const CategoryData = (props) => {
return fetch('https://www.amrutras.com/Category.php')
.then((response) => response.json())
})
.catch((error) => {
console.error(error)
})
}
export default CategoryData
and use it like
function App () {
const [categoryData, setCategoryData] = useState(null);
useEffect(() => {
CategoryData.then(res => setCategoryData(res));
}, []); Make sure to provide a dependency list to your useEffect otherwise you will end up in a infinite loop
}
Make it as a custom hook
import React, { useState } from 'react'
export const useCategoryData = (props) => {
const [Category, setCategory] = useState('')
useEffect(()=>{
fetch('https://www.amrutras.com/Category.php')
.then((response) => response.json())
.then((responseJson) => {
{
setCategory(responseJson)
// responseJson.map((item) => Alert.alert(item.Name))
}
// Showing response message coming from server after inserting records.
})
.catch((error) => {
console.error(error)
})
},[])
return {Category}
}
import it like
import {useCategoryData} from '.......'
const {Category} = useCategoryData()