微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么使用变量命名 react-final-form 组件会导致无限循环?

如何解决为什么使用变量命名 react-final-form 组件会导致无限循环?

我有一些代码可以为外部 JSON API 返回的每个条目创建一个 react-final-form 表单。

我试图使用变量 i 来设置 ControlInput 脉轮组件的名称。 (这个组件的定义是从 react-final-form with chakra example here 复制的)。 i 将在 API 中数组项的循环中递增。这以某种方式导致无限循环。 (示例代码中对return语句中的这段代码进行了注释)

但是,如果我只是在没有 i 变量的情况下设置名称,则一切正常。

我想了解为什么使用 i 会导致无限循环?

我想以某种方式使用 i 会导致 Form 以某种方式改变状态/重新渲染,但我现在确定如何/为什么会发生这种情况?

这是重现问题的笔: https://codepen.io/growinman/pen/GRmGyxX?editors=1010

代码原样工作正常,但如果我使用带注释的 return 语句,则会导致无限循环)

任何帮助将不胜感激!

这是代码的内联副本:

import * as finalForm from "https://cdn.skypack.dev/final-form@4.20.2";
import { Form,useField } from  "https://cdn.skypack.dev/react-final-form@6.5.3";
import * as reactRouterDom from "https://cdn.skypack.dev/react-router-dom@5.2.0";
import * as React from "https://cdn.skypack.dev/react@17.0.1";
import * as ReactDOM from "https://cdn.skypack.dev/react-dom@17.0.1";
import { Input }    from "https://cdn.skypack.dev/@chakra-ui/input@1.2.8";
import { vstack }   from "https://cdn.skypack.dev/@chakra-ui/react@1.6.5";
import { heading }   from "https://cdn.skypack.dev/@chakra-ui/layout@1.4.7";
import { FormControl,FormErrorMessage } from "https://cdn.skypack.dev/@chakra-ui/form-control@1.3.8";

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,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'))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。