问题
Setup/Scenario
I am using twitter api to fetch data and rendering it in twitter card using react-native-socials. The tweet data ( JSON ) is stored and served through my backend and rendered in the app.
I am using a Flatlist to render this data.
Problem
It's working fine for the first 3 loads, I am using pullToRefresh
in flatlist
to do a network call to get new data.
But when I try the 4th time it gets an undefined
element.
I've replaced the Twitter
element ( from react-native-socials lib ) with a Text
element, then there's no undefined
in the output and it doesn't crash.
This undefined
is what's causing the element to crash at a place where it's trying to get a particular key from the json data being passed to the Twitter
element.
More importantly I tried logging it up the chain but in vain. I had to go inside the library and add console.log
just where the object was being destructured and assigned.
Relevant Code
- The flatlist component
<FlatList
ref={refContainer}
data={feed}
keyExtractor={(post) => {
return post.id.toString();
}}
ListHeaderComponent={ListHeaderComponent}
renderItem={({ item }) => (
<View
style={{
padding: 10,
borderRadius: 35,
backgroundColor: colors.white,
}}
>
{item && item.type == postType.TWEET && (
<Twitter useCustomTweetExtendedData={item.content} />
)}
- Code from the library :
node_modules/react-native-socials/dist/src/Twitter/api.js
It errors out indata.created_at
and hence I added aconsole.log
export var adapter = function (data) {
console.log("typeof : "+ typeof(data) + " full_text : " + entities.decode(data?.full_text.slice(0, 10)));
var _a, _b, _c, _d, _e, _f;
var response = {
createdAt: data.created_at,
id: data.id,
Things I've already tried out :
- Supplying a default value - Did that still the error occurs
useEffect
forfeed
- Can't do this as the first timeloadFeed
is called to set thefeed
Some of the articles I referred before asking here :
- This discusses quite a few strategies
Questions
- Why the error only happens in the 3rd network call ( yes it's consistent ) ? - There's enough data to fetch for atleast 10 such calls
- Why isn't it logged in up the chain ?
- I've put checks like this one :
{item && item.type == postType.TWEET &&
and yet how come it goes down to the component and creates an error ? - How do I solve this
I read this - useState set method not reflecting change immediately but didn't understand how I could use this to solve my problem.
Thanks a lot.
Update
On suggestion on reddit here I added a null rejector kind of thing data.filter(obj => obj)
but that doesn't seem to help either :/
I am using flatlist to render a full array of objects, fetched from a backend server.
I checked the data using Postman, it was coming fine, no null values there.
Here's my feed
loading code.
const loadFeed = async (typeOfFeed, old = false) => {
setRefreshing(true);
let url = "";
if (old) {
url = FeedCursor.next;
}
const response = await postsApi.getPosts(typeOfFeed, url);
if (response.ok) {
if (response.data[0].id == feed[0]?.id) {
ToastAndroid.show("No new posts", ToastAndroid.SHORT);
} else if (response.data.length > 0) {
setFeedCursor({
next: response.headers.next,
previous: response.headers.previous,
});
}
response.data.filter((obj) => obj); // Updated this
setFeed(response.data);
}
} else {
ToastAndroid.show("No new posts", ToastAndroid.SHORT);
console.error(response.problem);
}
setRefreshing(false);
};
Another thing is that before this happens, on a previous load it mentions that :
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.
来源:https://stackoverflow.com/questions/64198006/async-usestate-leading-to-undefined-element-down-the-hierarchy