Skip to content

Commit

Permalink
feat: use array index for unique keys, and add propIndex prop
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisvxd committed Oct 26, 2018
1 parent 3861ba8 commit c5df9d4
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 12 deletions.
23 changes: 19 additions & 4 deletions src/__helpers__/burger.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
import * as React from "react";

export const Bun = ({ variant }: { variant: string }) => (
<div>{`${variant} bun`}</div>
export const Bun = ({
variant,
propIndex
}: {
variant: string;
propIndex?: number;
}) => (
<div>
<div>{propIndex && `Order: ${propIndex}`}</div>
{`${variant} bun`}
</div>
);

export const Patty = ({
id,
size,
ingredient
ingredient,
propIndex
}: {
id: number;
size: string;
ingredient: React.ReactNode;
propIndex?: number;
}) => (
<div id={`${id}`}>
<div>{propIndex && `Order: ${propIndex}`}</div>
{`${size} patty`}
{ingredient}
</div>
Expand All @@ -26,14 +38,17 @@ export const PattyIngredient = ({ variant }: { variant: string }) => (
export const Burger = ({
bun,
cheese,
children
children,
propIndex
}: {
bun: React.ReactNode;
chain: string;
cheese: boolean;
children: React.ReactNode;
propIndex?: number;
}) => (
<div>
<div>{propIndex && `Order: ${propIndex}`}</div>
<div>{bun}</div>
<div>{cheese && "cheese"}</div>
<div>{children}</div>
Expand Down
18 changes: 18 additions & 0 deletions src/__tests__/__snapshots__/index.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

exports[`ReactFromJSON to render a flat entry with a components attribute 1`] = `
<div>
<div />
<div>
<div>
<div />
sesame bun
</div>
</div>
Expand All @@ -14,6 +16,9 @@ exports[`ReactFromJSON to render a flat entry with a components attribute 1`] =
<div
id="0"
>
<div>
0
</div>
large patty
<div>
impossible
Expand All @@ -22,6 +27,9 @@ exports[`ReactFromJSON to render a flat entry with a components attribute 1`] =
<div
id="1"
>
<div>
Order: 1
</div>
large patty
<div>
beef
Expand All @@ -30,6 +38,7 @@ exports[`ReactFromJSON to render a flat entry with a components attribute 1`] =
</div>
<div>
<div>
<div />
sesame bun
</div>
</div>
Expand All @@ -38,8 +47,10 @@ exports[`ReactFromJSON to render a flat entry with a components attribute 1`] =

exports[`ReactFromJSON to render a recursive entry 1`] = `
<div>
<div />
<div>
<div>
<div />
sesame bun
</div>
</div>
Expand All @@ -50,6 +61,9 @@ exports[`ReactFromJSON to render a recursive entry 1`] = `
<div
id="undefined"
>
<div>
0
</div>
large patty
<div>
impossible
Expand All @@ -58,6 +72,9 @@ exports[`ReactFromJSON to render a recursive entry 1`] = `
<div
id="undefined"
>
<div>
Order: 1
</div>
large patty
<div>
beef
Expand All @@ -66,6 +83,7 @@ exports[`ReactFromJSON to render a recursive entry 1`] = `
</div>
<div>
<div>
<div />
sesame bun
</div>
</div>
Expand Down
23 changes: 15 additions & 8 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface Component {
interface ComponentLookupProps {
componentType: string;
componentIndex: number;
propIndex?: number;
}

export interface ComponentLookup {
Expand Down Expand Up @@ -44,7 +45,8 @@ class ReactFromJSON<

ComponentLookup = ({
componentIndex,
componentType
componentType,
propIndex
}: ComponentLookupProps) => {
const { components } = this.props;

Expand All @@ -58,12 +60,13 @@ class ReactFromJSON<
...component,
props: {
id: component.id || componentIndex, // Map id to component props if specified on root. Otherwise, use index.
propIndex: propIndex,
...component.props
}
});
};

resolveProp = (prop: any): any => {
resolveProp = (prop: any, index?: number): any => {
if (prop === null) {
return prop;
} else if (Array.isArray(prop)) {
Expand All @@ -76,23 +79,25 @@ class ReactFromJSON<
) {
const component: Component = prop;

return this.renderComponent(component);
return this.renderComponent(component, index);
}
}

return prop;
};

getNextKey(type: string) {
getNextKey(type: string, propIndex?: number) {
this.counter[type] = this.counter[type] || 0;
return `${type}_${this.counter[type]++}`;
const propIndexKey =
typeof propIndex !== "undefined" ? `_${propIndex}` : "";
return `${type}_${this.counter[type]++}${propIndexKey}`;
}

renderComponent(component: Component) {
renderComponent(component: Component, propIndex?: number) {
const { mapping } = this.props;
const { type, props } = component;
const resolvedProps = {};
const key = this.getNextKey(type);
const key = this.getNextKey(type, propIndex);

const propKeys = Object.keys(props);

Expand All @@ -109,7 +114,9 @@ class ReactFromJSON<
throw `Tried to render the "${type}" component, but it's not specified in your mapping.`;
}

return <MappedComponent key={key} {...resolvedProps} />;
return (
<MappedComponent key={key} propIndex={propIndex} {...resolvedProps} />
);
}

render() {
Expand Down

0 comments on commit c5df9d4

Please sign in to comment.