i got this error : Encountered two children with the same key, 610bebf8b6f3820b38b0c613. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version
but i use mongodb id so no way 2 id be them same
it happen when i load more items...
im using redux toolkit express mongoose
it happen sometimes not always
flatList :
<View style={{flex: 1, margin: 10, flexDirection: 'column'}}>
<Search />
{users.pending && !users.users.length ? (
<ActivityIndicator size="large" color="#0000ff" />
) : users.users.length === 0 ? (
<Text>No users</Text>
) : (
<FlatList
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
data={users.users}
renderItem={({item}) => <Card user={item} />}
keyExtractor={item => item._id}
onEndReachedThreshold={0}
onEndReached={handleLoadMore}
/>
)}
</View>
usersSlice :
getUsersSuccess: (state, action) => {
state.pending = false;
if (state.users.length === 0) {
state.users = action.payload;
} else {
state.users = [...state.users, ...action.payload];
}
state.skip = state.users.length;
},
apiCall
export const getUsers = async (dispatch, skip) => {
dispatch(getUsersStart());
try {
const res = await axios.get(`http://10.0.2.2:5000/users?skip=${skip}`);
dispatch(getUsersSuccess(res.data));
} catch (error) {
dispatch(getUsersError());
console.error('error => ', error.message);
}
};
server :
export const getUsers = async (req, res) => {
const skip =
req.query.skip && /^\d+$/.test(req.query.skip) ? Number(req.query.skip) : 0;
console.log(' req.qury.skip >>>>', req.query.skip);
try {
const users = await User.find({}, undefined, { skip, limit: 7 });
users.map((user) => {
user.name = decryptString(user.name, process.env.CRYPTO_PASSWORD);
});
res.status(200).json(users);
} catch (error) {
console.error(error.message);
res.status(500).json('Server Error');
}
};
i get
virtualizedList: You have a large list that is slow to update - make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc.
i think about delete duplicate item but i think not good choice
but i use mongodb id so no way 2 id be them same it happen when i load more items
your assumption can be wrong in multiple ways. Mongo IDs are unique in the database, but you could be getting duplicate values because of a variety of reasons.
I suspect that the API is giving you overlapping data and you merge new data with the old data without checking -
state.users = [...state.users, ...action.payload];
modify this to have a basic uniqueness check - and only add elements that are not already in the old list
Related
I am having trouble differentiating regular query requests from prefetch query requests in RTK Query. My goal is simple; I want a global loading spinner whenever a query fetches data. However, I also want to implement prefetch in a List so that paginating through different pages feels instantaneous for the end-user. What is happening now is that when I go to the next page in my List it is correctly prefetched so switching happens instantly. But then my global loading spinner is triggered for the prefetching of the page after that (which I obviously don't want happening). So I want to find out how to differentiate the prefetching requests from the regular fetching requests.
I have done extensive searching both on SO and the issue-tracker of redux-toolkit, but without success. Also, I have looked into the query requests that are made from prefetch requests and regular requests but those seem identical (which I would understand since the rtk-query team probably abstracted this).
Relevant code below:
LoadingWrapper.tsx
const LoadingWrapper = ({ children }) => {
// HOW TO DIFFERENTIATE HERE BETWEEN QUERIES?
const isSomeQueryPending = useSelector((state: RootState) => Object.values(state.api.queries).some((query) => query.status === 'pending'));
return (
<>
<LoadingScreen loading={isSomeQueryPending} />
{children}
</>
);
};
EntityList.tsx
import React, {
useCallback, useEffect, useState,
} from 'react';
import { useGetEntitiesQuery, usePrefetch } from '../../../Path/To/My/Api';
const DEFAULT_PAGE_SIZE = 50;
const EntityList: (): ReactElement => {
const [filter, setFilter] = useState<IEntityFilter>({
search: '',
offset: 0,
limit: DEFAULT_PAGE_SIZE,
});
const { data } = useGetEntitiesQuery(filter);
const prefetchPage = usePrefetch('getEntities');
const prefetchNext = useCallback(() => {
const prefetchFilter = { ...filter, offset: filter.offset + filter.limit };
prefetchPage(prefetchFilter);
}, [prefetchPage, filter.offset]);
useEffect(() => {
if (!(filter.offset + filter.limit >= data?.numberOfEntities)) {
prefetchNext();
}
}, [data, prefetchNext, filter.offset]);
... // Some data handling and showing of data in a list unrelated.
}
Api.ts
// This is my (injected) API endpoint
getEntities: builder.query<IEntities, IEntityFilter>({
query: (filter) => ({ url: 'entities', params: filter }),
transformResponse: (baseQueryReturnValue: IEntitiesResponse) => baseQueryReturnValue.body,
providesTags: (result) => (result
? [
...result.entities.map(({ object_id }) => ({ type: 'Entity', id: object_id } as const)),
{ type: 'Entity', id: 'LIST' },
]
: [{ type: 'Entity', id: 'LIST' }]
),
}),
So the question is as follows: how can I differentiate between the normal fetch query (useGetEntitiesQuery) and the prefetched version of that in my LoadingWrapper.tsx. And if this is not possible, what is the recommended way of achieving my goal?
I am trying to build a simple task website to get familiar with full stack development. I am using Next js and Strapi. I have tried all I can think of, but the data from the server just will not display on the frontend. It seems to me that the page loads too soon, before the data has been loaded in. However, I am not a full stack dev and am therefore not sure.
import axios from 'axios';
const Tasks = ({ tasks }) => {
return (
<ul>
{tasks && tasks.map(task => (
<li key={task.id}>{task.name}</li>
))}
</ul>
);
};
export async function getStaticProps() {
const res = await axios.get('http://localhost:1337/tasks');
const data = await res.data;
if (!data) {
return {
notFound: true,
}
} else {
console.log(data)
}
return {
props: { tasks: data },
};
};
export default Tasks;
I had the same issue. You need to call the api from the pages files in the pages folder. I don't know why this is but that's how it works.
I am trying to understand how to correctly use SelectFromResult from the official documentation:
https://redux-toolkit.js.org/rtk-query/usage/queries#selecting-data-from-a-query-result
I have extended the Pokemon example to retrieve a filtered list of Pokemons ending in "saur" using SelectFromResult but the output results in a loss of error and isLoading data
live sandbox here:
https://codesandbox.io/s/rtk-query-selectfromresult-vvb7l
relevant code here:
the endpoint extracts out the relevant data with a transformResponse:
getAllPokemon: builder.query({
query: () => `pokemon/`,
transformResponse: (response: any) => {
console.log("transformResponse", response);
return response.results;
}
})
and the hook fails if i try to selectFromResult and I lose error and isLoading variables as they are no longer returned from the hook. If I comment out the SelectFromResult option they are then correctly returned.
export const PokemonList = () => {
const { data, error, isLoading } = useGetAllPokemonQuery(undefined, {
selectFromResult: ({ data }) => ({
data: data?.filter((item: Pokemon) => item.name.endsWith("saur"))
})
});
useEffect(() => {
if (data) console.log("filtered result", data);
}, [data]);
return (
<div>
{data?.map((item: Pokemon) => (
<p>{item.name}</p>
))}
</div>
);
};
My question: I dont want to lose fetch status when trying to filter results using the recommended method. How do I modify the above code to correctly SelectFromResult and maintain the correct error, isLoading, etc status values from the hook?
Solution found:
I passed in and returned the additional required variables (and tested by adding a polling interval to allow me to disconnect to force and error)
const { data, error, isLoading } = useGetAllPokemonQuery(undefined, {
selectFromResult: ({ data, error, isLoading }) => ({
data: data?.filter((item: Pokemon) => item.name.endsWith("saur")),
error,
isLoading
}),
pollingInterval: 3000,
});
I'm currently using VuexFire to bind the Cloud Firestore to my Vuex State. I'm having some issues getting it to work, any help would be appreciated.
What I'm currently doing is the following:
Vue.js File:
methods:{
...mapActions("comments", ['bindArticleComments']),
},created(){
this.bindArticleComments()
},
actions/comments file
export const bindArticleComments = firestoreAction(({ bindFirestoreRef }) => {
return bindFirestoreRef('articleComments', collectionRef('comments'))
})
firebase services file
export const collectionRef = (collectionName) => {
return firestore().collection(collectionName)
}
What is strange about this is that I'm already doing the same procedure for a different Vuex state field. There it seems to be working without an issue. Is there anything that anyone thinks I might not be doing properly?
Strangely i got it working , although i'm struggling to understand how and why it's working.In my Vue js file i placed the this.bindArticleComments() after downloading the data and at creation.
methods:{
downloadComments(){
const { articlesCommentRef } = this.$fb
articlesCommentRef(this.loadedArticle.id).get()
.then(querySnapshot => {
this.setArticleComments(querySnapshot.docs.map((doc) => doc.data()))
this.bindArticleComments(this.loadedArticle.id)})
.catch(error => console.log("Error getting documents: ", error))
.finally(() => {this.$q.loading.hide()})
}
},
created(){
this.bindArticleComments(this.loadedArticle.id)
},
mounted(){
this.downloadComments()
}
Trying to make a simple CRUD app using react, axios and mongoose.
Here is my axios:
deleteUser(id) {
axios.delete(`${rootUrl}/api/users/${this.state.id}`, {
params: { id }
})
.then(response => {
// this.setState({ users: response.data });
console.log('deleteUser response', response, this.state);
});
}
Here is the relevant API route:
router.delete('/users/', (req, res) => {
const { id } = req.body;
User.findByIdAndDelete(id, (error, data) => {
if (error) {
console.log('error in deleting!');
throw error;
} else {
console.log('user has been deleted', data);
res.status(204).json(data);
}
});
});
It returns
DELETE /api/users/?id=5b34e5b5dfef8b4sd234567 204 47.816 ms - -
But when I GET users, the deleted user remains.
Here is the render I am mapping state into. I think I am pulling the id in properly but I am not sure what else to try:
{this.state.users.map(user => {
return (
<div className="Users1" key={user._id}>
<Card>
<CardBody>
<CardTitle>{user.username}</CardTitle>
<CardText>{user._id}</CardText>
<Button onClick={() => this.deleteUser(user._id)}
key={user._id}
type="button"
color="danger"
>
X
</Button>
</CardBody>
</Card>
</div>
);
})}
and here is state:
state = {
users: [],
id: ''
};
I had a similar problem. I had success by looking at the req.query property on the API server, rather than req.body:
const { id } = req.query;
I figured it out by dumping the entire req object to the console.
On the client side, my request did not include the id in the URL. I just included it in the params object. This seemed to help. So the equivalent call in your code would look something like this:
axios.delete(`${rootUrl}/api/users/`, {
params: { id }
})
I hope this helps. I'm still just learning React Native, so I'm hardly an expert. But I wanted to share what worked for me in case it helps others.