Skip to content

Commit

Permalink
Use hooks, not connect, for redux state
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathonherbert committed May 1, 2024
1 parent 5c891ba commit 7dc6bdc
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 35 deletions.
4 changes: 1 addition & 3 deletions fronts-client/src/bundles/recipesBundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ import { Recipe } from 'types/Recipe';
import recipe1 from './fixtures/recipe1.json';
import recipe2 from './fixtures/recipe2.json';

type RecipesState = Record<string, Recipe>;

export const { actions, reducer, selectors } =
createAsyncResourceBundle<RecipesState>('recipes', {
createAsyncResourceBundle<Recipe>('recipes', {
indexById: true,
// Add stub data in the absence of proper search data.
initialData: {
Expand Down
52 changes: 21 additions & 31 deletions fronts-client/src/components/card/recipe/RecipeCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,17 @@ import CardHeadingContainer from '../CardHeadingContainer';
import CardMetaHeading from '../CardMetaHeading';
import CardHeading from '../CardHeading';
import { selectCard } from 'selectors/shared';
import { connect } from 'react-redux';
import { State } from 'types/State';
import { selectors as recipeSelectors } from 'bundles/recipesBundle';
import { Recipe } from 'types/Recipe';
import CardBody from '../CardBody';
import CardMetaContainer from '../CardMetaContainer';
import ImageAndGraphWrapper from 'components/image/ImageAndGraphWrapper';
import { ThumbnailSmall } from 'components/image/Thumbnail';
import CardMetaContent from '../CardMetaContent';
import { upperFirst } from 'lodash';
import { useSelector } from 'react-redux';

interface ContainerProps {
interface Props {
onDragStart?: (d: React.DragEvent<HTMLElement>) => void;
onDrop?: (d: React.DragEvent<HTMLElement>) => void;
onDelete?: (uuid: string) => void;
Expand All @@ -33,37 +32,39 @@ interface ContainerProps {
fade?: boolean;
children?: React.ReactNode;
isUneditable?: boolean;
showMeta?: boolean;
}

interface RecipeProps extends ContainerProps {
card: Card;
recipe: Recipe;
}

const RecipeCardComponent = ({
export const RecipeCard = ({
id,
fade,
size = 'default',
textSize = 'default',
onDelete,
onAddToClipboard,
children,
card,
isUneditable,
collectionId,
frontId,
recipe,
showMeta,
...rest
}: RecipeProps) => {
}: Props) => {
const card = useSelector<State, Card>((state) => selectCard(state, id));
const recipe = useSelector((state) =>
recipeSelectors.selectById(state, card.id)
);

return (
<CardContainer {...rest}>
<CardBody data-testid="snap" size={size} fade={fade}>
<CardMetaContainer size={size}>
<CardMetaHeading>Recipe</CardMetaHeading>
<CardMetaContent>
{upperFirst(recipe.difficultyLevel)}
</CardMetaContent>
</CardMetaContainer>
{showMeta && (
<CardMetaContainer size={size}>
<CardMetaHeading>Recipe</CardMetaHeading>
<CardMetaContent>
{upperFirst(recipe?.difficultyLevel)}
</CardMetaContent>
</CardMetaContainer>
)}
<CardContent textSize={textSize}>
<CardSettingsDisplay
isBreaking={card.meta?.isBreaking}
Expand All @@ -74,25 +75,14 @@ const RecipeCardComponent = ({
/>
<CardHeadingContainer size={size}>
<CardHeading data-testid="headline" html>
{recipe.title}
{recipe?.title ?? 'No recipe found'}
</CardHeading>
</CardHeadingContainer>
</CardContent>
<ImageAndGraphWrapper size={size}>
<ThumbnailSmall url={recipe.featuredImage.url} />
<ThumbnailSmall url={recipe?.featuredImage.url} />
</ImageAndGraphWrapper>
</CardBody>
</CardContainer>
);
};

const mapStateToProps = (state: State, props: ContainerProps) => {
const card = selectCard(state, props.id);

return {
card,
recipe: recipeSelectors.selectById(state, card.id),
};
};

export const RecipeCard = connect(mapStateToProps)(RecipeCardComponent);
2 changes: 1 addition & 1 deletion fronts-client/src/lib/createAsyncResourceBundle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ function createAsyncResourceBundle<Resource>(
// e.g.the resource 'books' namespaced with 'shared' becomes SHARED/BOOKS
namespace?: string;
// The initial state of the reducer data. Defaults to an empty object.
initialData?: Resource;
initialData?: unknown;
} = {
indexById: false,
}
Expand Down

0 comments on commit 7dc6bdc

Please sign in to comment.