Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6287

React Native simple CRUD: how to make a page rerender when coming back from a detail page

$
0
0

I'm new to ReactNative and React and there is a thing I don't understand: how to make an already navigated page re-render when a child page changes its state. Let me explain better:

I implemented these components/pages:

  • ProfilesPage: a page with a FlatList with some profiles (name, surname...). Also with a BottomSheet popup here you can create a new profile or delete one.
  • ProfileDetailPage: when you select a single Profile from the ProfilesPage, it navigates here. In this page you can edit the profile's name and surname or delete it.

In the ProfilesPage everything works fine: I got the profiles array from my repository implementation and everytime a new profile is added or delete, I just use setState to rerender the whole page.

The problem comes when I am in the ProfileDetailPage: if a edit a profile detail name or surname or delete it and navigate back to the ProfilesPage, the page won't rerender!


My questions are:

  1. Is it true that by design when a page is re navigated it won't rerender?
  2. Is there an hook to force rerender when the page is navigated? I tried the following behavior but I'm not happy with it because the changes are applied after the transition animation and you clearly see that content is update.

What I've tried (related to question 2)

useEffect(() => {    const unsubscribe = props.navigation.addListener('focus', () => {        console.log('FOCUS');        setRefresh(previousState => !previousState); // To force re-render        setCurrentProfiles(ProfilesRepository.getAllProfiles());    });    return unsubscribe;}, [props.navigation]);
  1. Is Redux or another state management library what I'm searching for? It seems that it has hooks to rerender each page when the state changes.
  2. How to do what I want without another library? It seems that Redux puts a lot of boilerplate.

My code:

ProfilesRepository (Note that I keep profiles array cached, I don't see why I should re get it from the AsyncStorage everytime)

const initializeAsync = async () => {    if (!profiles) {        const profilesRaw = await AsyncStorage.getItem(profilesKey);        if (profilesRaw) {            profiles = JSON.parse(profilesRaw).map((p) =>                Object.assign(new Profile(), p)            );        } else {            profiles = Array<Profile>();        }    }};let profiles: Array<Profile> | null = null;initializeAsync();export const getAllProfiles = (): Profile[] => {    return profiles!;};export const getProfileById = (profileId: number): Profile | undefined => {    return profiles!.find((p) => p.id === profileId);};export const deleteProfileById = async (profileId: number) => {    const profileToDelete = profiles!.find((p) => p.id === profileId);    profiles = profiles!.filter((item) => item !== profileToDelete);    await AsyncStorage.setItem(profilesKey, JSON.stringify(profiles));};

ProfilesPage

const ProfilesPage = (props) => {    const [currentProfiles, setCurrentProfiles] = React.useState(        // Pass only the function without calling it to use the lazy init overload        // This is because otherwise everytime the bottomPopup does something, it redo getAllProfiles        ProfilesRepository.getAllProfiles    );    const [refresh, setRefresh] = React.useState(false);    // I need this to re-render the profiles list when coming back from a view    useEffect(() => {        const unsubscribe = props.navigation.addListener('focus', () => {            console.log('FOCUS');            setRefresh(previousState => !previousState); // To force re-render            setCurrentProfiles(ProfilesRepository.getAllProfiles());        });        return unsubscribe;    }, [props.navigation]);    const [currentSelectedProfile, setCurrentSelectedProfile] =        React.useState<Profile>();    const onDeleteSelectedProfileHandler = async () => {        await ProfilesRepository.deleteProfileById(            currentSelectedProfile!.id        );        setCurrentProfiles(ProfilesRepository.getAllProfiles());    };    return (<View style={styles.screen}><FlatList                data={currentProfiles}                keyExtractor={(item, index) => item.id.toString()}                renderItem={renderProfileItem}            />    // ...

Viewing all articles
Browse latest Browse all 6287

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>