0

I am following this Udemy course which goes through the development of an on-demand food ordering app. I'm loving the course so far, except that the instructor makes some questionable decisions all throughout the course; things that I have been taught by countless others and 10+ years of industry experience to never do.

One example of this is his duplication of a single React Native Paper Searchbar component to be used in two separate React Navigation screens. This is a violation of the DRY principle that I consider to be one of the most important design principles in programming.

His justification for this duplication is that he's making some minor styling changes in one instance of the component compared to the other. But IMHO, those differences could be handled in a much more elegant way.

Here's what I've got so far:

// search.component.js

import React, { useContext, useEffect, useState } from 'react';
import styled from 'styled-components/native';

import { Searchbar } from 'react-native-paper';

import { LocationContext } from '../../services/location/location.context';

const SearchBar = () => {
    const { searchQuery, location, error, setError, searchLocations } = useContext(LocationContext);

    const [lastSearch, setLastSearch] = useState('San Francisco');
    const [currentSearch, setCurrentSearch] = useState(searchQuery);

    // As an aside, I'd like to know if there's a better way to do this too!
    useEffect(() => {
        !error && setLastSearch(currentSearch);
    }, [location]); // eslint-disable-line react-hooks/exhaustive-deps

    return (
        <Searchbar
            placeholder="Search for a location..."
            value={error ? lastSearch : currentSearch}
            onChangeText={newSearch => {
                setCurrentSearch(newSearch);
                setError(null);
            }}
            onSubmitEditing={() => searchLocations(currentSearch)}
        />
    );
};

// restaurant.search.component.js
const RestaurantSearchContainer = styled.View`
    padding: ${props => props.theme.spacing.md};
`;

export const RestaurantSearch = () => (
    <RestaurantSearchContainer>
        <Search />
    </RestaurantSearchContainer>
);

// map.search.component.js
const MapSearchContainer = styled.View`
    padding: ${props => props.theme.space[3]};
    position: absolute;
    top: ${props => props.theme.space[4]};
    width: 100%;
    z-index: 1;
`;

export const MapSearch = () => (
    <MapSearchContainer>
        <SearchBar />
    </MapSearchContainer>
);

The LocationContext doesn't do much ATM besides loading some mock location data from a JSON file, but it will eventually use the Google Places API to provide data on the restaurants in a particular area. RestaurantSearch is a search bar on the Restaurants screen, while MapSearch is the exact same component but on the Map screen, and therefore styled a bit differently as you can see.

IMHO using this inheritence pattern keeps the code much cleaner and more maintainable - the whole purpose of the DRY principle and the reason why it's so important. But I don't know how to tell React to re-render the map when the user searches on the Restaurants screen, or vice-versa.

Any guidance with this, including tips on how I could improve the code further would be very much appreciated :-)

Kenny83
  • 769
  • 12
  • 38

1 Answers1

0

Never mind, after moving on to another feature of the course and making some changes it is suddenly working now! I always hate it when bugs just magically disappear like this, since they're likely to come back at some point...but for now I am good to go. Thanks anyway :-)

Kenny83
  • 769
  • 12
  • 38