How can I implement D.R.Y. in my FlatList when re-using the same props passed to an OnPress?

Viewed 54

Learning React Native I set out to use FlatList and React Navigation and while everything works I've been searching for a way to prevent calling the same props. In my Parent component:

const Parent = ({ navigation }) => {
  return (
    <>
      <StatusBar hidden />
      <FlatList
        data={data}
        renderItem={({ item }) => (
          <Child
            title={item.name}
            color={item.color}
            onPress={() =>
              navigation.navigate(routes.PATH, {
                title: item.name,
                foo: item.foo,
                color: item.color,
              })
            }
          />
        )}
        keyExtractor={item => item.id.toString()}
      />
    </>
  )
}

Parent.propTypes = {
  navigation: PropTypes.object.isRequired,
}

I pass down everything to my Child component:

const Child = ({ onPress = () => {}, title, color }) => {
  return (
    <TouchableOpacity onPress={onPress} activeOpacity={0.8}>
      <View style={[styles.row, { backgroundColor: color ? color : colors.primary }]}>
        <Text style={styles.text}>{title}</Text>
      </View>
    </TouchableOpacity>
  )
}

Child.propTypes = {
  onPress: PropTypes.func.isRequired,
  title: PropTypes.string.isRequired,
  color: PropTypes.string.isRequired,
}

Is there a way I can reuse title and color in the prop and also pass down to the function?

1 Answers

I'm not really working with react-native. you could just pass Child into renderItem. The only issue is you need to access navigation onPress. Maybe you could use context for it.

Theoretically this should work


const Context = createContext();

const Child = ({ item }) => {
  const {title, color} = item;
  const navigation = useContext(Context);
  const onPress = useCallback(() => navigation.navigate(routes.PATH, {
    title: item.name,
    foo: item.foo,
    color: item.color,
  }));

  return (
    <TouchableOpacity onPress={onPress} activeOpacity={0.8}>
      <View style={[styles.row, { backgroundColor: color ? color : colors.primary }]}>
        <Text style={styles.text}>{title}</Text>
      </View>
    </TouchableOpacity>
  )
}


const Parent = ({ navigation }) => { 
  const createChild = (item) => 
  return (
    <>
      <Context.Provider value={navigator}>
        <StatusBar hidden />
        <FlatList
          data={data}
          renderItem={Child}
          keyExtractor={item => item.id.toString()}
        />
      </Context.Provider>
    </>
  )
}
Related