如何解决为什么使用变量命名 react-final-form 组件会导致无限循环?
我有一些代码可以为外部 JSON API 返回的每个条目创建一个 react-final-form
表单。
我试图使用变量 i
来设置 Control
的 Input
脉轮组件的名称。 (这个组件的定义是从 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 举报,一经查实,本站将立刻删除。