Nextjs dynamic function import (not component)
Asked Answered
D

0

6

I'm working in a nextjs app. I'd like to dynamically import a function dependent on the path that's provided as a prop to a component. Today, I use a map of id to a function and use the id provided in the path to retrieve the function and use it in my component. However, I am skeptical that this takes advantage of code-splitting.

Here's a minimal example that illustrates my point. Imagine, though, that the functions are not as simple as detailed here--imagine that there are many and each is large and consequently we would be better off to only send the function necessary to render to the client. That is, in the example case, only send add if the algoId in the path is add (and the same for the other ids).

import { FunctionComponent, ReactElement, useState } from "react";
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps, GetStaticPropsResult } from "next";
import { ParsedUrlQuery } from "querystring";
import * as React from "react";

type MyAlgo = (a: number, b: number) => number;
const add: MyAlgo = (a: number, b: number): number => a + b;
const multiply: MyAlgo = (a: number, b: number): number => a * b;
const myAlgos: Map<string, MyAlgo> = new Map([["add", add], ["multiply", multiply]]);

interface MyParams extends ParsedUrlQuery {
    algoId: string;
}

interface MyProps {
    algoId: string;
}

export const getStaticPaths: GetStaticPaths<MyParams> = (): Promise<GetStaticPathsResult<MyParams>> => {
    return Promise.resolve({
        paths: [...myAlgos.keys()].map(algoId => ({ params: { algoId } })),
        fallback: false
    });
};

export const getStaticProps: GetStaticProps<MyProps, MyParams> =
    ({ params }): Promise<GetStaticPropsResult<MyProps>> => {
        if (!params?.algoId) {
            throw new Error("No algo id");
        }
        return Promise.resolve({
            props: {
                algoId: params.algoId,
            }
        });
    };

const MyPage: FunctionComponent<MyProps> = ({ algoId }): ReactElement => {
    const algo = myAlgos.get(algoId);
    if (!algo) {
        throw new Error(`No algo for algo id ${algoId}`);
    }
    const [a, setA] = useState(0);
    const [b, setB] = useState(0);
    const [res, setRes] = useState(0);
    return <div>
        <input
            type="number"
            placeholder="a"
            onChange={(e) => {
                setA(parseInt(e.target.value));
                setRes(algo(a, b));
            }}
        />
        <input
            type="number"
            placeholder="b"
            onChange={(e) => {
                setB(parseInt(e.target.value));
                setRes(algo(a, b));
            }}
        />
        <p>{res}</p>
    </div>
};

export default MyPage;

Is there a way to achieve dynamic imports for the client-side so as to take advantage of code-splitting? I noticed that there's a way to dynamically import a component but that's not what I'm looking for. I want the component to stay constant for this page type and for my function to change dependent on the path.

Thanks.

Dispel answered 2/1, 2021 at 19:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.