Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds main entry to packages package.json #424

Merged
merged 4 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,15 @@ const handleRequest = (req, res) => {
};
```

Tip: wouter can pre-fill `ssrSearch`, if `ssrPath` contains the `?` character. So these are equivalent:

```jsx
<Router ssrPath="/goods?sort=asc" />;

// is the same as
<Router ssrPath="/goods" ssrSearch="sort=asc" />;
```

On the client, the static markup must be hydrated in order for your app to become interactive. Note
that to avoid having hydration warnings, the JSX rendered on the client must match the one used by
the server, so the `Router` component must be present.
Expand Down
1 change: 1 addition & 0 deletions packages/wouter-preact/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"types/**/*.d.ts",
"types/*.d.ts"
],
"main": "esm/index.js",
"exports": {
".": {
"types": "./types/index.d.ts",
Expand Down
1 change: 1 addition & 0 deletions packages/wouter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"types/**/*.d.ts",
"types/*.d.ts"
],
"main": "esm/index.js",
"exports": {
".": {
"types": "./types/index.d.ts",
Expand Down
17 changes: 8 additions & 9 deletions packages/wouter/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ export const Router = ({ children, ...props }) => {
// holds to the context value: the router object
let value = parent;

// when `ssrPath` contains a `?` character, we can extract the search from it
const [path, search] = props.ssrPath?.split("?") ?? [];
if (search) (props.ssrSearch = search), (props.ssrPath = path);

// what is happening below: to avoid unnecessary rerenders in child components,
// we ensure that the router object reference is stable, unless there are any
// changes that require reload (e.g. `base` prop changes -> all components that
Expand Down Expand Up @@ -220,17 +224,12 @@ export const Link = forwardRef((props, ref) => {
: h("a", { ...restProps, href, onClick, children, ref });
});

const flattenChildren = (children) => {
return Array.isArray(children)
? [].concat(
...children.map((c) =>
c && c.type === Fragment
? flattenChildren(c.props.children)
: flattenChildren(c)
)
const flattenChildren = (children) =>
Array.isArray(children)
? children.flatMap((c) =>
flattenChildren(c && c.type === Fragment ? c.props.children : c)
)
: [children];
};

export const Switch = ({ children, location }) => {
const router = useRouter();
Expand Down
39 changes: 39 additions & 0 deletions packages/wouter/test/router.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,45 @@ it("alters the current router with `parser` and `hook` options", () => {
expect(router.hook).toBe(hook);
});

it("accepts `ssrPath` and `ssrSearch` params", () => {
const { result } = renderHook(() => useRouter(), {
wrapper: (props) => (
<Router ssrPath="/users" ssrSearch="a=b&c=d">
{props.children}
</Router>
),
});

expect(result.current.ssrPath).toBe("/users");
expect(result.current.ssrSearch).toBe("a=b&c=d");
});

it("can extract `ssrSearch` from `ssrPath` after the '?' symbol", () => {
let ssrPath: string | undefined = "/no-search";
let ssrSearch: string | undefined = undefined;

const { result, rerender } = renderHook(() => useRouter(), {
wrapper: (props) => (
<Router ssrPath={ssrPath} ssrSearch={ssrSearch}>
{props.children}
</Router>
),
});

expect(result.current.ssrPath).toBe("/no-search");
expect(result.current.ssrSearch).toBe(undefined);

ssrPath = "/with-search?a=b&c=d";
rerender();

expect(result.current.ssrPath).toBe("/with-search");
expect(result.current.ssrSearch).toBe("a=b&c=d");

ssrSearch = "x=y&z=w";
rerender();
expect(result.current.ssrSearch).toBe("a=b&c=d");
});

it("shares one router instance between components", () => {
const RouterGetter = ({ el }: { el: ReactElement }) => {
const router = useRouter();
Expand Down
Loading