what time to call flatlist scrollToEnd method would work - react-native

I set flatlist's data in the constructor, and call flatlist scrollToEnd in the componentDidMount method, I think it should scroll to end, but it did't. And I click one button to call scrollToEnd method, the flatlist scroll to end.
So I want to know when should I call flatlist's method to change it without click.

try scrollToEnd with timeout
componentDidMount() {
setTimeout(() => {
this.refs.list.scrollToEnd();
}, 100);
}
When you call without timeout your FlatList not render at that time so scrollToEnd not working

Related

FlatList stop scroll when button press during scroll

i would like to know if there is any way to stop scroll event on iOs and Android
Steps to reproduce
scroll FlatList / ScrollView
click any button
already tried "onScroll" but when i set scroll ref.scrollTo it will scroll when stroll stops
Example GIF:
This is just an idea which I think might work, you may have to test it yourself.
Assuming you have the following state, controlling the modal.
const [open, setOpen] = useState(false);
You can probably add a onScroll event to Flatlist (onScroll is inherited from ScrollView), then
const onScroll = (e) => {
if (open) e.preventDefault();
}
If there is a delay before e.preventDefault is called, since setting state is async, you may want to use useRef() instead of useState() for checking if (open) since scroll happens quickly.
Another idea is to probably use a listener for the flat list, to listen to scroll, using same logic above.

Render useEffect/Async function from a difference screen

I have an async function and a useEffect that fetches data once.
const [data, setData] = useState([]);
async function fetchData() {
fetch(`${baseURL}api/v1/data/${userId}`)
.then((response) => response.json())
.then((response) => {
try {
if (response.length > 0) {
setData(response);
} else {
setData([]);
// console.log(response);
}
} catch (err) {
console.log('no response');
alert(err);
}
});
}
useEffect(() => {
fetchData();
}, [userId, data]);
I could remove the array on the use effect but it will always run the function if I do that.
So when I open the screen, it will fetch the latest data. However, if I want to add a new data from a different screen, it wont trigger the async nor the useEffect function. How should I tell RN that there is a new data? Would AsyncStorage work? to update a data from one screen and apply the data here? I am open for suggestions on how to proceed.
What I meant by a different screen: A register screen and a view screen. In this case, I already opened the View Screen before I open the register screen so view screen is already rendered.
In React Navigation and most of the navigation libraries, screens don't get unmounted from the stack when it's navigated to another screen. For example if you have a list of something and then you press to "+" button to navigate to the "new item" screen to add a new one, when you press back button, since the previous "list" screen was not unmounted from the stack, useEffect won't be triggered, and you won't get the new data.
There are a couple of solutions for this case:
You can hold your data in a global state, and when you update an item from another screen, after a successful API call, you can also update the global state. You can look for React Context, MobX or Redux for this.
You can pass parent's state with a callback from one screen to another if they are not that apart from each other. So that in the "new data" screen, you can call that callback function to change the parent screen's state too.
Third, and IMO the best way is using a hook called useFocusEffect by React Navigation itself: https://reactnavigation.org/docs/use-focus-effect
I hope these will help.

willFocus event in react navigation 5

I need to fetch data before focus event. I saw that there was an willFocus event in react navigation 4 but it seems that the event was removed in react navigation 5.
componentDidMount cannot do the trick because I want to fetch data as soon as possible even before the screen comes into focus each time the user navigate to my screen.
You could do something like:
/**
* Your redux action should set loading-state to false after
* fetch-operation is done...
*/
reduxActionDoingFetch();
useEffect(() => {
if (reduxActionDoingFetch_Loading === false) {
Navigation.navigate('YourTargetScreen');
}
}, [reduxActionDoingFetch_Loading]);
You CANNOT fetch data before componentDidMount. That's literally the first thing happens when a new screen is rendered.
Regarding fetching data each time when the screen is focused, you need to use focus event as mentioned in the migration guide: https://reactnavigation.org/docs/upgrading-from-4.x/#navigation-events
The focus event equivalent to willFocus from before. It fires as soon as the screen is focused, before the animation finishes. I'm not sure what you mean by it fires too late.
Also, for data fetching, there is a special hook: useFocusEffect
https://reactnavigation.org/docs/use-focus-effect/
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
// do something
});
return unsubscribe;
}, [navigation]);

React Native TextInput setState() hides keyboard

Please check on the snack link,
https://snack.expo.io/#banid/textinput
The TextInput on the filter view(shows when the button is pressed) hides keyboard when ever I call setState(). I call setState to update the value of TextInput. Bcause of this I can't type continuously on the TextInput. Is this a bug or am I doing something wrong?? Thank you
The problem is that you are creating a new (anonymous) function that renders the header of the FlatList on every update
<FlatList .... ListHeaderComponent={() => this.showHeader()} />
So a new TextInput is being created instead of updating the existing one.
Solution:
change ListHeaderComponent={() => this.showHeader()}
to ListHeaderComponent={this.showHeader} as ListHeaderComponent can be a function
https://facebook.github.io/react-native/docs/flatlist#listheadercomponent
Similar Issue:
https://github.com/react-native-training/react-native-elements/issues/559
It seems the focus is being removed from the TextInput after every setState, here's a work around you can use:
Change
this.setState({
filterSearchText: text,
data: newData,
});
To
this.setState({
filterSearchText: text,
data: newData,
}, () => {
this.searchInput.focus();
});
What this does is it brings back the focus to searchInput after a setState is called

how can i send callback to my parent view when call Actions.pop in react-native-router-flux

I am using https://github.com/aksonov/react-native-router-flux for navigation in react native.How can I send callback to my parent view when I call pop actions on it.
onPressed() {
Actions.pop();
}
This is how I call pop action on it but I need to send updated value to previous view.
will I finally solve it by calling empty refresh with props after delay
Actions.popTo('pageOne');
setTimeout(() => {
Actions.refresh({name:'zzzzar'});
console.log("zzzz");
}, 10);