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

How do I test a conditionally rendered component in React Native?

$
0
0

I'm building a React Native app that lists live music gigs. The user can toggle between showing the current day's gigs or the current week's gigs.If the user presses the 'Gigs Today' button, the state variable showWeek is set to false; if the 'Gigs This Week' button is pressed, showWeek is set to true.
The components GigsByDay is rendered when showWeek is set to false; GigsByWeek is rendered when it is true:

Parent component ListByDay.tsx

type ListScreenNavigationProp = listProps["navigation"];interface Props {  navigation: ListScreenNavigationProp;}const ListByDay: FC<Props> = ({ navigation }): JSX.Element => {  const [showWeek, setShowByWeek] = useState<boolean>(false);  const currentDateMs:number = Date.now()  const gigs = useGigs();  const gigsToday = getGigsToday(gigs, currentDateMs);  const gigsThisWeek = getGigsThisWeek(gigs, currentDateMs);  const gigsToRender = showWeek ? (<GigsByWeek gigsThisWeek_grouped={gigsThisWeek} navigation={navigation} />  ) : (<GigsByDay navigation={navigation} gigsFromSelectedDate={gigsToday} />  );  return (<View><View style={styles.buttonContainer}><TouchableOpacity          onPress={() => setShowByWeek(false)}          style={styles.touchable}          testID = 'gigsTodayButton'><Text style={showWeek ? null : styles.selected}>Gigs today</Text></TouchableOpacity><TouchableOpacity          onPress={() => setShowByWeek(true)}          style={styles.touchable}><Text testID="header" style={showWeek ? styles.selected : null}>            Gigs this week</Text></TouchableOpacity></View>      {gigsToRender}</View>  );};

I want to test that this toggle is working correctly, using React Native Testing Library and Jest.

My approach is to i) isolate the GigsByDay component, ii) trigger a press event for the 'Gigs Today' button, and then iii) test if either the state is false, or that the GigsByDay component has been rendered/is visible to the user.
My question is this - how do test a state change/if a component has been rendered? And are either of these ways actually the right approach?

Here's the test I've written so far, which has failed:

test("that 'showWeek' state is switched to false when 'Gigs Today' pressed", () => {  render(<ListByDay />);  const gigsToday = screen.getByTestId("gigs-today")  fireEvent.press(screen.getByTestId("gigsTodayButton"))  expect(getByTestId("gigs-today").state.showWeek).toBe(false) // what should be done here?})

Here's the GigsByDay component:

import { FC } from 'react';import { FlatList,TouchableOpacity,StyleSheet,View,Image,Text } from 'react-native'import { listProps } from '../routes/homeStack';import { GigObject } from '../routes/homeStack';type ListScreenNavigationProp = listProps['navigation']interface Props {  gigsFromSelectedDate: GigObject[],  navigation: ListScreenNavigationProp}const GigsByDay:FC<Props> = ({ gigsFromSelectedDate, navigation }):JSX.Element => (<FlatList    testID = 'gigs-today'    data={gigsFromSelectedDate}    keyExtractor={item => item.id}    renderItem={({ item }) => (<TouchableOpacity        style={styles.gigCard}        onPress={() =>          navigation.navigate('GigDetails', {            venue: item.venue,            gigName: item.gigName,            blurb: item.blurb,            isFree: item.isFree,            image: item.image,            genre: item.genre,            dateAndTime: {...item.dateAndTime},            tickets: item.tickets,            id:item.id          })        }><View style={styles.gigCard_items}><Image            style={styles.gigCard_items_img}            source={require('../assets/Icon_Gold_48x48.png')}          /><View><Text style={styles.gigCard_header}>{item.gigName}</Text><Text style={styles.gigCard_details}>{item.venue}</Text></View></View></TouchableOpacity>    )}  />)

Viewing all articles
Browse latest Browse all 6290

Trending Articles



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