Why does using a variable to name a react-final-form component cause an infinite loop?

Solution for Why does using a variable to name a react-final-form component cause an infinite loop?
is Given Below:

I have some code that creates a react-final-form form for each entry returned by an external JSON API.

I was trying to use a variable i to set the name of a Control‘d Input chakra component. (The definition of this component is copied from the react-final-form with chakra example here). i would get incremented in a loop over the items of the array from the API. This is somehow causing an infinite loop. (This code in the return statement is commented in the sample code)

However if I just set the name without the i variable, everything works fine.

I’m trying to understand why using i would cause the infinite loop?

I suppose that using i somehow causes the Form to change state/re-render somehow but I’m now sure how/why that would happen?

Here’s a pen reproducing the issue:
https://codepen.io/growinman/pen/GRmGyxX?editors=1010

(the code as-is works fine, but if I use the commented return statement, it results in the infinite loop)

Any help would be appreciated!

and here’s an inline copy of the code:

import * as finalForm from "https://cdn.skypack.dev/[email protected]";
import { Form, useField } from  "https://cdn.skypack.dev/[email protected]";
import * as reactRouterDom from "https://cdn.skypack.dev/[email protected]";
import * as React from "https://cdn.skypack.dev/[email protected]";
import * as ReactDOM from "https://cdn.skypack.dev/[email protected]";
import { Input }    from "https://cdn.skypack.dev/@chakra-ui/[email protected]";
import { VStack }   from "https://cdn.skypack.dev/@chakra-ui/[email protected]";
import { Heading }   from "https://cdn.skypack.dev/@chakra-ui/[email protected]";
import { FormControl, FormErrorMessage } from "https://cdn.skypack.dev/@chakra-ui/[email protected]";

async function handleErrors(response) {
  if (!response.ok) {
      throw await response.json();
  }
  return response;
}

const makeGetRequest = (requestUrl) => {
  const requestOptions = {
    method: 'GET'
  }

  return fetch(requestUrl, requestOptions)
  .then(handleErrors)
  .then((response) => {
    return response.json()
  })
}


const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

const onSubmit = async values => {
  await sleep(300)
  window.alert(JSON.stringify(values, 0, 2))
}


const ProductReview = (props) => {
    let i=0;
    console.log('rendering')
    const [unreviewedProducts, setUnreviewedProducts] = React.useState({})
    
    React.useEffect(
        () => {
            console.log('In useeffect')
            makeGetRequest('https://mocki.io/v1/aea3b014-5a38-4366-a71c-87b2e53eb07c').then(
              // Create a map for unreviewedProducts from the 'unreviewedProductsJson' array, keyed by the uuid
                (unreviewedProductsJson) => {
                    setUnreviewedProducts(
                        unreviewedProductsJson.reduce(
                            (mapSoFar, currentObj) => ({...mapSoFar, [currentObj.uuid]: currentObj}), {}
                        )
                    )
                }
            )
        },
        []
    )

    return (
        <>
            <Heading as="h1" fontSize={[16,32]} textAlign="center" marginTop="20px">
                Products
            </Heading>
            <VStack
                alignItems="stretch"
                margin="20px auto 0 auto"
                w="80%"
                maxW="600px"
            >
                {
                    Object.values(unreviewedProducts).map((unreviewedProduct) => {
                        console.log('In map()')
                        return (
                            <Form
                                key={unreviewedProduct.uuid}
                                onSubmit={onSubmit}
                                validate={() => {}}
                                render={({
                                handleSubmit,
                                form,
                                errors,
                                submitting,
                                pristine,
                                values
                                }) => {
                                    console.log('In render')
                                    console.log(i)
                                    i = i + 1
                                    
                                    return (
                                    <VStack
                                        marginTop="103px"
                                    >
                                        
                                        <InputControl name={unreviewedProduct.uuid} placeholder="Website" />
                                    </VStack>
                                )
                              
//                               return (
//                                     <VStack
//                                         marginTop="103px"
//                                     >
                                        
//                                         <InputControl name={i} placeholder="Website" />
//                                     </VStack>
//                                 )
                            }
                                    }
                            />
                        )
                    })
                }
            </VStack>
        </>
    )
}


// These were mainly copied from the chakra-ui/react-final-form example
// from here: https://final-form.org/docs/react-final-form/examples/chakra
const Control = ({ name, ...rest }) => {
    const {
        meta: { error, touched }
    } = useField(name, { subscription: { touched: true, error: true } })
    return <FormControl {...rest} isInvalid={error && touched} />
}


const Error = ({ name }) => {
    const {
        meta: { error }
    } = useField(name, { subscription: { error: true } })

    return <FormErrorMessage>{error}</FormErrorMessage>
}

const InputControl = ({ name }) => {
    const { input, meta } = useField(name)
    return (
      <>
        <Control name={name} my={4}>
            <Error name="s" />
            <Input
            {...input}
            isInvalid={meta.error && meta.touched}
            id={name}
            />
        </Control>
      </>
    )
  }

ReactDOM.render(<ProductReview />, document.getElementById('root'))