I only need to display the data of one object that I get here
const {posts, loading} = useSelector((state) => ({...state.posts}))
useEffect(() => {
dispatch(getPost(id))
}, []);
"posts" is array
when I want to display it simply this way
<h4>cat: {posts[0].category}</h4>
<h4>aut: {posts[0].username}</h4>
it only works only for the first time and after one page refresh the array (posts) turns out to be empty. But when I do it like this
<>
{
posts.map(post=>(
<CardDetailsComponent post={post} key={post._id}/>
))
}
</>
(CardDetails component looks exactly like first example but in different component)
everything is fine. Why?
Related
I am trying to get the images data from flickr. I am getting the response but not able to display the image.I have tried using useEffect to fetch the api and useState variable to store images array. Still it was getting called two times.
const DisplayImages = () => {
let photos = [];
fetch(
` https://www.flickr.com/services/rest/?method=flickr.galleries.getPhotos&api_key=***********************&gallery_id=************&format=json&nojsoncallback=1`
)
.then((response) => response.json())
.then((res) => {
const images = res;
console.log(res);
photos = images.photos.photo;
});
return (
<>
<div className="imagescontainer">
{photos.map((photo) => {
console.log(photo);
let url = `https://farm${photo.farm}.staticflickr.com/${photo.server}/${photo.id}_${photo.secret}`;
<>
{/* <img src={require(url)} alt="img" /> */}
</>
})}
</div>
</>
);
};
I expected the images to be rendered.
It's getting called twice because React is probably configured to be in strict mode in development, which causes hooks to be called twice.
Second, you're using a locally-scoped variable photos to hold state, when you need to use useState instance, otherwise React won't know when the state changes and re-render the component.
Third, it looks like you're setting photos, which is initialized with an empty array, to a single instance of a photo.
I am creating a React App which will be used to display Dynamic Maps for DnD (vid files). Based on the User Input in a select field, a video player will get the specific video file from the firebase firestore, where I store the video files.
const Streamplayer = ({vidSelection}) => { //vidSelection is the event.target.value from the Select Input Field (basically a String)
const [links, setLinks] = useState([])
console.log(vidSelection);
useEffect(() => {
getLinks()
}, [])
useEffect(() => {
console.log(links)
}, [links])
function getLinks(){
const vidRef = collection(db, 'links');
getDocs(vidRef).then(response => {
console.log(response.docs)
const lnks = response.docs.map(doc => ({
data: doc.data(),
id: doc.id,
}))
setLinks(lnks)
}).catch(error => console.log(error.message));
}
function getVid(){
const toReturn = links.map((link) => link.data.vidSelection);//I want to change whatever gets returned based on input
console.log(toReturn)
return toReturn;
}
return (
<video
controls={false}
autoPlay
muted
loop
className="Video"
key={getVid()}
>
<source src={getVid()} type="video/mp4" />
</video>
)
}
export default Streamplayer
So in the method getVid() I request the data stored in the Firebase Firestore "Links" Collection and I want to change whichever I get based on the userInput. So if the User chooses the map "Grotto", I want to make the call "link.data.grotto". But since vidSelection is a String, I can't simply insert it in this call. Any Ideas how to solve this?
You can make useEffect get re-called when props change, by providing the prop in the dependency list for useEffect. Simply change your first useEffect call to:
useEffect(() => {
getLinks()
}, [vidSelection])
When the selection changes, useEffect will fire and call getLinks, which will update your state.
(Also, minor suggestion: remove the getVid() function, and just set a const videoSource = links.map((link) => link.data.vidSelection) in the function body. Right now you're calling the function twice which will cause the mapping to happen twice, and I think it's generally clearer to have consts flow directly from state, makes it easier to reason about state.)
I am using AsyncStorage to store some values frequently and I want to display the values on the screen. I am using useffect() to read all the values and print them. It works fine for the first time, but from next time onwards new values are not gettings displayed. Can I implement an event listener so that I can keep refreshing the value displayed on the screen?
const [view, setview] = useState('');
useFocusEffect(
React.useCallback(() => {
fromasyncstorage();
}, []),
);
const fromasyncstorage = async () => {
const valuex = await AsyncStorage.getItem('message');
if (valuex) {
setview(valuex);
}
};
//setview is used to display the message on screen
return(
<View>
<Text>{view}</Text>
</View>
)
Maybe this can be achieved by adding an abstraction on top of the storage.
Please refer to the link for more description: https://github.com/react-native-async-storage/async-storage/issues/401
im doing a mern app, and i need to map over an array of objects, but the problem is that, the way i structure the data didn't put me in a good position to do it...
Here's the thing
this is my data
Inside task, there is an object, and inside that object we got more stuff...
I need to get to this data and show it in my website
So far, i only got to the creator
const tasks = useSelector(state => state.tasks.map(room => room.creator));
console.log(tasks);
The role of selectors is to select data from the state manager (redux in that context).
So firstly, fix your selector and select the tasks:
const tasks = useSelector(state => state.tasks);
Secondly,
Iterate over the tasks array and output the data you want:
const ExampleComponent = () => {
const tasks = useSelector(state => state.tasks);
return (
<ul>
{
tasks.map((task, index) => {
<li key={index}>{task.task}</li>
}
}
</ul>
);
}
I have a code which calls an API with a certain number of data and receives them. I wish for the 2nd call to add the newly retrieved data to be added to the already existing data using React-query library.
My code so far is :
const fetchData = async ({queryKey : [key , pages]}) => {
return (await fetch(`http://jservice.io/api/random?count=${pages}`)).json()
}
function App() {
const [state, setState] = React.useState(10);
const {isLoading, error, data , } = useInfiniteQuery(['general' , state], fetchData , {keepPreviousData : true} )
setTimeout(() => {
setState(20)
}, 4444);
console.log(data)
return (
<div className="App">
h
</div>
);
}
I wish to hit the 4444 time line marker by adding the newly fetched data to the existing data solely by using React-query hooks.
How can I achieve this?
You need to use the fetchNextPage from the query. Call this to load the next page. Either onClick or after a timeout.
<button onClick={fetchNextPage}>Load more</button>
Also do not set setTimeout in the render function, since it will be called and executed on every render, which will remove your progress.
Dont track the current page yourself but let react-query handle it.
Just set the getNextPageParam function to return how you need to get the next page and extract that as pageParam from the query context in fetchData
To render the data, you need to map over the pages returned from the query inside data and for each page, query over the items returned:
{isSuccess &&
data.pages.map((page, index) => (
<div key={index}>
{page.results.map((poke) => (
<div key={poke.name}>{poke.name}</div>
))}
</div>
))}
Here is a sandbox with pokemon.