I have a chat application using NextJS and I'm trying to add a way to send GIPHY images.
I have things set up but I'm having trouble switching between the giphy.search()
and giphy.trending()
calls. Basically I have a component that displays the grid that contains the trending GIFs at that time. But above that grid, I have a text input where the user can search for specific GIFs. The value of this search input is stored in the parent component's state.
I initially tried having just one component for showing the grid (only trending):
<Grid
fetchGifs={(offset: number) => giphy.trending({ offset: offset, limit: 10 })}
width={width}
columns={2}
gutter={8}
onGifClick={onClick}
/>
Since that worked, I tried to add the ability to search:
<Grid
fetchGifs={
(offset: number) => {
if (searchTerm) {
return giphy.search(searchTerm, { sort: 'relevant', lang: 'en', offset: offset, limit: 10 });
} else {
return giphy.trending({ offset: offset, limit: 10 });
}
}
}
width={width}
columns={2}
gutter={8}
onGifClick={onClick}
/>
However, the SDK is erroring out. So I ended up making two separate components - one for the trending GIFs, and the other for a searchable GIFs:
import { Grid } from '@giphy/react-components';
import { GiphyFetch } from '@giphy/js-fetch-api';
import Constants from '@/utilities/constants';
import { GIFFetcherProps } from '@/types';
const TrendingGIPHY = ({ width, onClick }: GIFFetcherProps) => {
const giphy = new GiphyFetch(Constants.GIPHY_API_KEY);
return (
<Grid
fetchGifs={(offset: number) => giphy.trending({ offset: offset, limit: 10 })}
width={width}
columns={2}
gutter={8}
onGifClick={onClick}
/>
);
};
export default TrendingGIPHY;
import { Grid } from '@giphy/react-components';
import { GiphyFetch } from '@giphy/js-fetch-api';
import Constants from '@/utilities/constants';
import { SearchGIFFetcherProps } from '@/types';
const SearchGIPHY = ({ searchTerm, width, onClick }: SearchGIFFetcherProps) => {
const giphy = new GiphyFetch(Constants.GIPHY_API_KEY);
return (
<Grid
fetchGifs={(offset: number) =>
giphy.search(searchTerm, { sort: 'relevant', lang: 'en', offset: offset, limit: 10 })
}
width={width}
columns={2}
gutter={8}
onGifClick={onClick}
/>
);
};
export default SearchGIPHY;
And then on the parent component, I just determine which GIPHY component to render:
{searchTerm ? (
<SearchGIPHY
searchTerm={searchTerm}
width={width}
onClick={handleGIFClick}
/>
) : (
<TrendingGIPHY width={width} onClick={handleGIFClick} />
)}
This is somewhat working but not really. It's able to switch back and forth between the correct components based on the searchTerm
. However, the searchable component only searches for the first letter. I'm out of ideas on how to implement this.
I couldn't find anything related to this approach anywhere, however, it seems like it uses some kind of technique to memoize the fetch so no unnecessary re-render and fetch will be done.
Fortunately, after digging more doc which led me to their Github pate, it has a runnable demo and it has the working example! https://github.com/Giphy/giphy-js/blob/master/packages/react-components/README.md#bare-bones-example
After reviewing their code, here's some thoughts
Grid
component -- Their demo has a property for Grid
component the your code doesn't have... which is key
In other words, you can solve the problem where only first letter is being parsed by adding it, like this --
<Grid
key={searchTerm} // <-- HERE
fetchGifs={(offset: number) =>
giphy.search(searchTerm, { sort: 'relevant', lang: 'en', offset: offset, limit: 10 })
}
width={width}
columns={2}
gutter={8}
onGifClick={onClick}
/>
(the demo has the prop key
to be more complex, but you can make your own judgement)
key={`${channelSearch} ${term} ${activeChannel?.user.username}`}
Reference