https://next.ant.design/components/form-cn/#components -form-demo-form-in-modal
Basta usar useForm diretamente. Refiro-me ao exemplo na camada pop-up.
const CollectionCreateForm = ({onCancel}) => {
const [form] = Form.useForm ();
form.setFieldsValue ({
categoryName: caseDetail.categoryName,
});
Retorna (
maskClosable = {false}
title = "Modificar as informações básicas do projeto"
okText = "OK"
cancelText = "Cancelar"
onCancel = {onCancel}
onOk = {() => {
Formato
.validateFields ()
.então (valores => {
form.resetFields ();
onCreate (valores);
})
.catch (info => {
window.console.log ('Falha na validação:', informações);
});
}}
>
Eu só quero poder usar este useForm normalmente
index.js: 1 Aviso: a instância criada por useForm
não está conectada a nenhum elemento do formulário. Esqueceu de passar form
prop?
em CollectionCreateForm ....
const [formulário] = Form.useForm ();
form.setFieldsValue ({
categoryName: caseDetail.categoryName,
});
| Meio ambiente | Informações |
| --- | --- |
| antd | 4.0.0-rc.5 |
| Reagir | 16.8.6 |
| Sistema | mac10.15.3 |
| Navegador | cromo |
Vim diretamente de acordo com o site oficial, mas esse erro foi relatado em todos os lugares, e eu fiquei sem palavras.
Olá @LamTech. Forneça uma reprodução online bifurcando este link https://u.ant.design/codesandbox-repro ou um repositório GitHub mínimo. Problemas marcados por Need Reproduce
serão fechados se não houver atividades em 7 dias .
Olá @LamTech , precisamos que você forneça um exemplo aqui para criar um codesandbox ou fornecer um repositório GitHub mínimo. Os problemas que não forem acompanhados em 7 dias serão encerrados automaticamente.
A chave é que eu uso esse método, mas ele continua relatando esse aviso de erro.
O mesmo problema aqui, mas não podemos reproduzi-lo no codesandbox.
+1
Adicione o atributo forceRender ao Modal
Você pode adicionar um atraso ao método setFieldsValue
Chame form.resetFields (); é o que parece. O http: // localhost : 8001 / components / form-cn / # components-form-demo-form-context iniciado localmente será relatado.
+1
Este aviso aparecerá ao usar setFieldsValue, mas pode ser apresentado sem problemas,
Passei na instância de useForm
O formulário no Modal não será renderizado por padrão, você pode consultar a resposta de @ se7en00 e adicionar forceRender
ao Modal. Ou chame setFieldsValue
e resetFields
depois que Modal for exibido e a renderização for concluída.
Ao usar a versão V4 (existe formulário no componente de função), fiquei incomodado com esse problema por dois dias e quase caí (foi relatado um erro, mas não afetou o uso). Por fim, li https://ant.design / e https: // next. .ant.design / Descubra o uso de formulário em componentes de função e classes deve compreender e distinguir entre os componentes de função
useEffect (() => {
return () => {
form.resetFields ();
};
})
É todo o componente da função que aciona a destruição em return () => {....} (não testado se o formulário foi destruído neste momento)
Descrição do documento: destroyOnClose | Destrua os elementos filhos do Modal ao fechar, o padrão é falso. forceRender | Renderização obrigatória de Modal, padrão falso.
Solução: Modal's forceRender = true, destroyOnClose = false, quando Modal for destruído (fechado), nenhum erro será reportado. O formulário pode ser encontrado quando o código interno é executado, mas o aviso de id de controle de entrada repetido será relatado (é mais elegante que o erro).
Mesmo problema +1
se o seu código envolve setFieldsValue
ou outras funções semelhantes, chame-o após os nós renderizados
useEffect(() => {
form.setFieldsValue({
id: 1
})
}, [])
ou
componentDidMount() {
form.setFieldsValue({
id: 1
})
}
Resolveu meu problema
Acho que nenhuma das opções acima pode resolver completamente este problema. Você pode adicionar um atributo ao formulário para indicar se o formulário tem campos e deixar que o próprio desenvolvedor determine se deve executar o código a seguir
O mesmo acontece aqui
Ainda não corrigido?
Tentei todos os métodos mencionados acima, não funcionou
O formulário no Modal não será renderizado por padrão, você pode consultar a resposta de @ se7en00 e adicionar
forceRender
ao Modal. Ou chamesetFieldsValue
eresetFields
depois que Modal for exibido e a renderização for concluída.
Quando eu uso a gaveta, embora o Drawer tenha a API forcerender, a API da gaveta, que é diferente do Modal, não é a renderização forçada, mas a pré-renderização, e então o mesmo erro é relatado, então existe uma solução? Como julgar que a renderização está completa?
Resolvi. No drawer, usar getContainer = {false} pode resolver. Acho que o Modal é o mesmo.
Eu uso getContainer = {false} na gaveta. O Modal também deve ter o mesmo problema. Você pode tentar
Você pode usar useRef para salvar o objeto Form e pode determinar se useRef existe antes de usar o formulário;
mesmo problema aqui. formulário é atribuído, mas continua falhando.
Se você chamar form.setFieldsValue diretamente no efeito, mesmo se forceRenter for adicionado e o Modal reaberto, ainda haverá este aviso. A solução temporária só pode ser setTimeout (() => form.setFieldsValue, 0) no efeito.
Para resolver o problema da gaveta, usei getContainer = {false} e não reportei o aviso.Se o mesmo problema ocorrer, você pode tentar e esperar que possa ser escrito claramente no documento Form.
Obrigado, este método resolveu o mesmo problema 👍
Seu método é viável, você pode explicar o princípio?
Minha solução alternativa, crie um ref
por useState
quando Form
foi renderizado, então verifique ref
antes de usar a instância do formulário.
interface FormModalProps {
data?: RoleProps;
visible: boolean;
onCancel?: () => void;
onSubmit?: (values: Store) => void;
submitting: boolean;
}
const FormModal: React.FC<FormModalProps> = props => {
const [form] = Form.useForm();
const [formRef, setFormRef] = useState(); // <---- set the ref when Form Rendered
const { data, onSubmit, onCancel, visible, submitting } = props;
// reset Form when modal close
useEffect(() => {
if ( !props.visible && formRef) { // <---- check ref before use the form instance
form.resetFields();
}
}, [props.visible]);
// fill Form when modal open
useEffect(() => {
if (visible && formRef) { // <---- check ref before use the form instance
form.setFieldsValue({
...data,
});
}
}, [props.data]);
// handle form onFinish
const handleFormFinish = (values: Store) => {
if (onSubmit) {
onSubmit(values);
}
};
// handle modal ok
const handleOk = () => {
if (!form) return;
form.submit();
};
return (
<Modal
title="Modal"
confirmLoading={submitting}
onOk={handleOk}
onCancel={onCancel}
visible={visible}
width={640}
>
<Form ref={setFormRef} form={form} onFinish={handleFormFinish}>
<Form.Item name="title" label="Title" >
<Input />
</Form.Item>
</Form>
</Modal>
);
};
Sem mais avisos de novo!
é difícil discutir em inglês?
se você usar setFieldsValue, tente seguir o código para substituir (minha ideia tola)。
<Modal **destroyOnClose** >
<Form **initialValues={formValues}**>
</Form>
</Modal>
Eu tenho que trabalhar.
Inicialmente, eu estava chamando o componente antd de
<Form blabla >
Em seguida, adicionei o prop de formulário no componente Form -
<Form form={form} blabla >
Aqui, o {form} vem de const [form] = Form.useForm();
Doc (que eu estava seguindo) -
https://ant.design/components/form/#components -form-demo-form-in-modal
Seu caso pode ser diferente.
https://codesandbox.io/s/form-in-modal-to-create-ant-design-demo-xvcyv
Mesmo problema, qualquer corpo pode consertar isso ??
Consulte linxianxi acima, https://github.com/ant-design/ant-design/issues/21543#issuecomment -598515368
Modal eu posso
<Modal
destroyOnClose={false}
getContainer={false}
forceRender
>
Modal eu posso
<Modal destroyOnClose={false} getContainer={false} forceRender >
Obrigado, resolvi este problema adicionando adereços forceRender no Modal
const [form] = Form.useForm()
<Form form={form} >
....
</Form>```
this did the trick for me.
Eu tenho que trabalhar.
Inicialmente, eu estava chamando o componente antd de
<Form blabla >
Em seguida, adicionei o prop de formulário no componente Form -
<Form form={form} blabla >
Aqui, o {form} vem de
const [form] = Form.useForm();
Doc (que eu estava seguindo) -
https://ant.design/components/form/#components -form-demo-form-in-modalSeu caso pode ser diferente.
Isso consertou para mim também. Eu estava usando o formulário em uma gaveta, não em um modal
A combinação secreta para mim foi:
useEffect (() => {
if (forma && visível) {
if (atual) {
setTimeout (() => form.setFieldsValue ({
...atual,
}), 0);
} outro {
form.resetFields ();
}
}
}, [atual]);
Mesmo erro aqui sem passagem modal e de prop de formulário para o componente de formulário
https://codesandbox.io/s/basic-usage-ant-design-demo-6llbw?file=/index.js : 1618-1661
Mesmo erro aqui sem passagem modal e de prop de formulário para o componente de formulário
https://codesandbox.io/s/basic-usage-ant-design-demo-6llbw?file=/index.js : 1618-1661
Correção para o seu: https://codesandbox.io/s/basic-usage-ant-design-demo-ksuz8?file=/index.js
você deve mover o form.getVieldValue para um componente Form.Item
<Form.Item
shouldUpdate={(prevValues, curValues) =>
prevValues.username !== curValues.username
}
noStyle
>
{() => <div>{form.getFieldValue("username")}</div>}
</Form.Item>
outro método seria usar um useRef ()
Draw + Form. Para Modal + Form, o método se aplica.
const MyComp = React.memo(() => {
const [form] = Form.useForm();
const { getFieldValue } = form;
const category = getFieldValue('category'); // It's the culprit
return (/* something */);
})
Uso adequado: métodos de formulário
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender}
>
{({ getFieldValue }) => {
return getFieldValue('gender') === 'other' ? (
<Form.Item name="customizeGender" label="Customize Gender" rules={[{ required: true }]}>
<Input />
</Form.Item>
) : null;
}}
</Form.Item>
const MyComp = React.memo(() => {
const [form] = Form.useForm();
const { getFieldValue } = form;
const category = getFieldValue('category'); // It's the culprit
return (/* something */);
})
A maneira correta de usar: chamada de método de formulário
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender}
>
{({ getFieldValue }) => {
return getFieldValue('gender') === 'other' ? (
<Form.Item name="customizeGender" label="Customize Gender" rules={[{ required: true }]}>
<Input />
</Form.Item>
) : null;
}}
</Form.Item>
Isso acontece porque o elemento do formulário não foi renderizado, mas Você definiu valores para o formulário. Eu acho que este é um conhecimento básico sobre react e hooks .. Você pode usar setTimeout para esperar o formulário renderizado.
Mas a melhor maneira de definir o valor inicial do formulário é
<Form
initialValues={{
name: 'Hafid',
age: '35'
}}
onFinish={onFinish}
>
ou com este método
`` `js
const [valores, setValues] = React.useState ({})
React.useEffect (() => {
// obter valores de dados de serviço da web ou API
// fecth (...)
if (values_from_api) {
setValues (values_from_api);
}
}, [])
return <>
E se eu precisar usar valores de formulário em meu próprio gancho personalizado?
Com o Ant 3 eu fiz assim:
const [updating, updateInfo] = useMyOwnCustomHookForSubmitAction(getFieldsValue());
const submitForm = () => {
validateFields((err) => {
if (!err) updateInfo();
});
};
<Form>...</Form>
Com o Ant 4, se eu tentar fazer assim, vou obter este erro do tópico.
const [form] = useForm();
const [updating, updateInfo] = useMyOwnCustomHookForSubmitAction(getFieldsValue());
const submitForm = () => {
validateFields((err) => {
if (!err) updateInfo();
});
};
<Form form={form}>...</Form>
O formulário está em modal, forceRender = true, destroyOnClose = false definido. O que estou fazendo de errado?
Ao usar a versão V4 (existe um formulário no componente de função), fiquei incomodado com esse problema por dois dias e quase caí (foi relatado um erro, mas não afetou o uso) .Finalmente, li https: // ant. design / e https: // next. .ant.design / Descubra o uso de forma em componentes de função e classes deve compreender e distinguir entre os componentes de função
useEffect (() => {
return () => {
form.resetFields ();
};
})
É todo o componente da função que aciona a destruição em return () => {....} (não testado se o formulário foi destruído neste momento)
Descrição do documento: destroyOnClose | Destrua os elementos filhos do Modal ao fechar, o padrão é falso. forceRender | Renderização obrigatória de Modal, padrão falso.
Solução: Modal's forceRender = true, destroyOnClose = false, quando Modal for destruído (fechado), nenhum erro será reportado. O formulário pode ser encontrado quando o código interno é executado, mas o aviso de id de controle de entrada repetido será relatado (é mais elegante que o erro).
Eu também encontrei esse problema, resolvi dessa forma
Configuração modal forceRender | Renderização forçada
No formulário Modla, name = {['modal', 'cityCode']}
Name = {['search', 'cityCode']} ou name = 'cityCode' no formulário de filtro
Desta forma, todos os avisos podem ser resolvidos e os 2 elementos encontrados com aviso de ID não exclusivo não serão relatados ⚠
Você pode usar useRef para se referir à ref do formulário, use o método em formRef.current
const formRef = useRef()
return (<Form ref={formRef}>
{
(formRef.current && formRef.current.getFieldsValue('key') === 1)
&&
(<Input />)
}
</Form>)
O formulário no Modal não será renderizado por padrão, você pode consultar a resposta de @ se7en00 e adicionar
forceRender
ao Modal. Ou chamesetFieldsValue
eresetFields
depois que Modal for exibido e a renderização for concluída.
Adicionar o atributo forceRender ao Modal é totalmente inútil
O exemplo no bloco oficial também avisa
Ao usar a versão V4 (existe um formulário no componente de função), fiquei incomodado com esse problema por dois dias e quase caí (foi relatado um erro, mas não afetou o uso) .Finalmente, li https: // ant. design / e https: // next. .ant.design / Descubra o uso de forma em componentes de função e classes deve compreender e distinguir entre os componentes de função
useEffect (() => {
return () => {
form.resetFields ();
};
})
É todo o componente da função que aciona a destruição em return () => {....} (não testado se o formulário foi destruído neste momento)
Descrição do documento: destroyOnClose | Destrua os elementos filhos do Modal ao fechar, o padrão é falso. forceRender | Renderização obrigatória de Modal, padrão falso.
Solução: Modal's forceRender = true, destroyOnClose = false, quando Modal for destruído (fechado), nenhum erro será reportado. O formulário pode ser encontrado quando o código interno é executado, mas o aviso de id de controle de entrada repetido será relatado (é mais elegante que o erro).
Este método pode ser resolvido, mas se o operador ternário estiver visível? É usado para determinar a camada externa de Modal e forceRender = true, destroyOnClose = false é assim:
{visible ? : <Modal visible={visible} forceRender destroyOnClose={false}><Form form={form} onFinish={handleFinish}>...</Form></Modal> : null}
Há um problema: apenas a máscara é exibida, mas a caixa com marcadores não é exibida
Defina forceRender = true e destroyOnClose = false desta forma e, em seguida, use form.resetFields () quando o pop-up for fechado onOk ou onCancel e nenhum outro erro será relatado.
<Modal
visible={visible}
forceRender
destroyOnClose={false}
>
<Form form={form} onFinish={handleFinish}>...</Form>
</Modal>
Mas se você usar o operador ternário visible? Para determinar a camada externa do Modal e definir forceRender = true, destroyOnClose = false assim:
{visible
? <Modal
visible={visible}
forceRender
destroyOnClose={false}
>
<Form form={form} onFinish={handleFinish}>...</Form>
</Modal>
: null
}
Há um problema: apenas a máscara é exibida, mas a caixa com marcadores não é exibida
A solução oficial
Ligação
Ao usar a versão V4 (existe um formulário no componente de função), fiquei incomodado com esse problema por dois dias e quase caí (foi relatado um erro, mas não afetou o uso) .Finalmente, li https: // ant. design / e https: // next. .ant.design / Descubra o uso de forma em componentes de função e classes deve compreender e distinguir entre os componentes de função
useEffect (() => {
return () => {
form.resetFields ();
};
})
É todo o componente da função que aciona a destruição em return () => {....} (não testado se o formulário foi destruído neste momento)
Descrição do documento: destroyOnClose | Destrua os elementos filhos do Modal ao fechar, o padrão é falso. forceRender | Renderização obrigatória de Modal, padrão falso.
Solução: Modal's forceRender = true, destroyOnClose = false, quando Modal for destruído (fechado), nenhum erro será reportado. O formulário pode ser encontrado quando o código interno é executado, mas o aviso de id de controle de entrada repetido será relatado (é mais elegante que o erro).Eu também encontrei esse problema, resolvi dessa forma
Configuração modal forceRender | Renderização forçada
No formulário Modla, name = {['modal', 'cityCode']}
Name = {['search', 'cityCode']} ou name = 'cityCode' no formulário de filtro
Desta forma, todos os avisos podem ser resolvidos e os 2 elementos encontrados com aviso de ID não exclusivo não serão relatados ⚠
[O nome do formulário será usado como o prefixo do id do campo do formulário] Portanto, não há aviso sobre 2 elementos encontrados com id não exclusivo
getContainer = {false} como propriedade modal + ter o modal visível quando chamo form.resetFields () funciona para eu não mostrar o aviso
useEffect(() => {
if (form && visible) {
form.resetFields();
}
}, [visible]);
Desta forma, destroyOnClose também pode ser verdadeiro
Eu uso useRef em vez de Form.useFrom para obter a instância do Form, funciona para mim
const [visible, setVisible] = useState(false)
let form = useRef(null)
const closeModal = () => {
setVisible(false)
form.resetFields()
}
return (
<Modal
title="test"
visible={visible}
onCancel={closeModal}
footer={null}
>
<Form
name="test"
layout="vertical"
onFinish={onFinish}
ref={instance => { form = instance }}
>
<Form.Item
label="item"
name="item"
>
<Input />
</Form.Item>
<Form.Item
style={{
textAlign: 'right',
}}
>
<Space size="middle">
<Button type="primary" htmlType="submit">
submit
</Button>
<Button onClick={closeModal}>
cancle
</Button>
</Space>
</Form.Item>
</Form>
</Modal>
)
Apenas meus dois centavos: esse erro apareceu para mim quando tentei redefinir um formulário que não estava montado, então adicionar uma dependência a uma constante necessária resolveu.
useEffect(() => {
if (data) { // data is used to populate initialValues
form.resetFields();
}
}, [form, data])
EDITAR: praticamente o que @fabripeco disse: D
Eu uso o formulário no Popover, useRef
pode ser usado para mim, acho que pode ser usado para modal
const formRef = useRef(null);
<Popover
content={renderEdit()}
visible={isEdit}
onVisibleChange={onToggleEdit}
>
<span onClick={onToggleEdit}>
{name}
</span>
</Popover>
function renderEdit() {
return (
<Form
initialValues={{ newName: name }}
form={form}
ref={formRef}
>
</Form>
);
}
function onToggleEdit() {
if (isEdit) {
toggleEdit(false);
} else if (!isEdit) {
if (formRef.current) {
form.setFieldsValue({
newName: name
});
}
toggleEdit(true);
}
}
Minha solução alternativa, crie um
ref
poruseState
quandoForm
foi renderizado, então verifiqueref
antes de usar a instância do formulário.interface FormModalProps { data?: RoleProps; visible: boolean; onCancel?: () => void; onSubmit?: (values: Store) => void; submitting: boolean; } const FormModal: React.FC<FormModalProps> = props => { const [form] = Form.useForm(); const [formRef, setFormRef] = useState(); // <---- set the ref when Form Rendered const { data, onSubmit, onCancel, visible, submitting } = props; // reset Form when modal close useEffect(() => { if ( !props.visible && formRef) { // <---- check ref before use the form instance form.resetFields(); } }, [props.visible]); // fill Form when modal open useEffect(() => { if (visible && formRef) { // <---- check ref before use the form instance form.setFieldsValue({ ...data, }); } }, [props.data]); // handle form onFinish const handleFormFinish = (values: Store) => { if (onSubmit) { onSubmit(values); } }; // handle modal ok const handleOk = () => { if (!form) return; form.submit(); }; return ( <Modal title="Modal" confirmLoading={submitting} onOk={handleOk} onCancel={onCancel} visible={visible} width={640} > <Form ref={setFormRef} form={form} onFinish={handleFormFinish}> <Form.Item name="title" label="Title" > <Input /> </Form.Item> </Form> </Modal> ); };
Sem mais avisos de novo!
resolvido perfeitamente!
Duas razões para este Aviso:
1
Eu resolvo usar isso:
<Modal
getContainer={false}
// destroyOnClose
>
A solução oficial
Ligação
Perfeito, adicione forceRender ao modal
Por que você não expõe formHooked
e permite que os usuários julguem por si mesmos, você não se sente cansado com os métodos acima?
Comentários muito úteis
Resolvi. No drawer, usar getContainer = {false} pode resolver. Acho que o Modal é o mesmo.
Eu uso getContainer = {false} na gaveta. O Modal também deve ter o mesmo problema. Você pode tentar