Link 内部反应最终形式不起作用
Link inside react final form does not work
在使用自定义错误组件的 React 最终形式中,link 之后的它不起作用。如果我使用一个简单的 span link 而不是错误组件就可以正常工作。
- 第一个输入有焦点
- 我点击下面的link
- 出现错误,但是link没有打开
- 当我再次点击 link 时,link 被打开
预期的行为是什么?
错误应该出现在下面,因为我模糊了输入
link 应该在第一次点击时打开
代码
基于https://final-form.org/docs/react-final-form/examples/record-level-validation
index.js
import React from "react";
import { render } from "react-dom";
import Styles from "./Styles";
import { Form, Field } from "react-final-form";
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const onSubmit = async values => {
await sleep(300);
window.alert(JSON.stringify(values, 0, 2));
};
const Error = ({ name }) => (
<Field
name={name}
subscription={{ touched: true, error: true }}
render={({ meta: { touched, error } }) =>
touched && error ? <span style={{ color: "red" }}>{error}</span> : null
}
/>
);
const App = () => (
<Styles>
<h1>React Final Form Example</h1>
<h2>Password / Confirm Validation</h2>
<a
href="https://final-form.org/react"
target="_blank"
rel="noopener noreferrer"
>
Read Docs
</a>
<Form
onSubmit={onSubmit}
validate={values => {
const errors = {};
if (!values.username) {
errors.username = "Required";
}
return errors;
}}
render={({ handleSubmit, form, submitting, pristine, values }) => (
<form onSubmit={handleSubmit}>
<a
href="https://final-form.org/react"
target="_blank"
rel="noopener noreferrer"
>
[works] Down Read Docs
</a>
<Field name="username">
{({ input, meta }) => (
<div>
<label>Username</label>
<input
{...input}
type="text"
placeholder="Username"
autoFocus
/>
</div>
)}
</Field>
<Error name="username" />
<a
href="https://final-form.org/react"
target="_blank"
rel="noopener noreferrer"
>
[does not work] Read Docs
</a>
<div className="buttons">
<button type="submit" disabled={submitting}>
Submit
</button>
<button
type="button"
onClick={form.reset}
disabled={submitting || pristine}
>
Reset
</button>
</div>
<pre>{JSON.stringify(values, 0, 2)}</pre>
</form>
)}
/>
</Styles>
);
render(<App />, document.getElementById("root"));
Styled.js
import styled, { css } from 'styled-components'
const btn = (light, dark) => css`
white-space: nowrap;
display: inline-block;
border-radius: 5px;
padding: 5px 15px;
font-size: 16px;
color: white;
&:visited {
color: white;
}
background-image: linear-gradient(${light}, ${dark});
border: 1px solid ${dark};
&:hover {
background-image: linear-gradient(${light}, ${dark});
&[disabled] {
background-image: linear-gradient(${light}, ${dark});
}
}
&:visited {
color: black;
}
&[disabled] {
opacity: 0.6;
cursor: not-allowed;
}
`
const btnDefault = css`
${btn('#ffffff', '#d5d5d5')} color: #555;
`
const btnPrimary = btn('#4f93ce', '#285f8f')
export default styled.div`
font-family: sans-serif;
h1 {
text-align: center;
color: #222;
}
h2 {
text-align: center;
color: #222;
}
& > div {
text-align: center;
}
a {
display: block;
text-align: center;
color: #222;
}
form {
max-width: 500px;
margin: 10px auto;
border: 1px solid #ccc;
padding: 20px;
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
border-radius: 3px;
& > div {
display: flex;
flex-flow: row nowrap;
line-height: 2em;
margin: 5px;
& > label {
color: #333;
width: 110px;
font-size: 1em;
line-height: 32px;
}
& > input,
& > select,
& > textarea {
flex: 1;
padding: 3px 5px;
font-size: 1em;
margin-left: 15px;
border: 1px solid #ccc;
border-radius: 3px;
}
& > input[type='checkbox'] {
margin-top: 7px;
}
& > div {
margin-left: 16px;
& > label {
display: block;
& > input {
margin-right: 3px;
}
}
}
& > span {
line-height: 32px;
margin-left: 10px;
color: #800;
font-weight: bold;
}
}
& > .buttons {
display: flex;
flex-flow: row nowrap;
justify-content: center;
margin-top: 15px;
}
button {
margin: 0 10px;
&[type='submit'] {
${btnPrimary};
}
&[type='button'] {
${btnDefault};
}
}
pre {
border: 1px solid #ccc;
background: rgba(0, 0, 0, 0.1);
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
padding: 20px;
}
}
`
沙盒Link
https://codesandbox.io/s/link-in-react-final-form-z2g2b?fontsize=14&hidenavigation=1&theme=dark
哇!这是一个有趣的。错误是将 link 从鼠标光标下移出,因此当您 "mouse up" 完成单击时,鼠标不再位于 hyperlink.
上方
如果您按住鼠标按钮然后在释放之前将其移动到跟随 link,则 link 将 "work"。
可以通过将错误设置为 space 来修复它是否显示,这样它就不会将页面的其余部分向下移动。
严格回答问题:
touched && error ?
<span style={{ color: "red" }}>{error}</span> :
<span> </span>
当您进出场时,这也将消除场的不断移动。
还有其他选项:
- 将必填项放在字段末尾,就像密码字段一样
- 仅在提交时验证
- 将错误显示为工具提示
- 在渲染前使用短暂的超时
在使用自定义错误组件的 React 最终形式中,link 之后的它不起作用。如果我使用一个简单的 span link 而不是错误组件就可以正常工作。
- 第一个输入有焦点
- 我点击下面的link
- 出现错误,但是link没有打开
- 当我再次点击 link 时,link 被打开
预期的行为是什么?
错误应该出现在下面,因为我模糊了输入 link 应该在第一次点击时打开
代码
基于https://final-form.org/docs/react-final-form/examples/record-level-validation
index.js
import React from "react";
import { render } from "react-dom";
import Styles from "./Styles";
import { Form, Field } from "react-final-form";
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const onSubmit = async values => {
await sleep(300);
window.alert(JSON.stringify(values, 0, 2));
};
const Error = ({ name }) => (
<Field
name={name}
subscription={{ touched: true, error: true }}
render={({ meta: { touched, error } }) =>
touched && error ? <span style={{ color: "red" }}>{error}</span> : null
}
/>
);
const App = () => (
<Styles>
<h1>React Final Form Example</h1>
<h2>Password / Confirm Validation</h2>
<a
href="https://final-form.org/react"
target="_blank"
rel="noopener noreferrer"
>
Read Docs
</a>
<Form
onSubmit={onSubmit}
validate={values => {
const errors = {};
if (!values.username) {
errors.username = "Required";
}
return errors;
}}
render={({ handleSubmit, form, submitting, pristine, values }) => (
<form onSubmit={handleSubmit}>
<a
href="https://final-form.org/react"
target="_blank"
rel="noopener noreferrer"
>
[works] Down Read Docs
</a>
<Field name="username">
{({ input, meta }) => (
<div>
<label>Username</label>
<input
{...input}
type="text"
placeholder="Username"
autoFocus
/>
</div>
)}
</Field>
<Error name="username" />
<a
href="https://final-form.org/react"
target="_blank"
rel="noopener noreferrer"
>
[does not work] Read Docs
</a>
<div className="buttons">
<button type="submit" disabled={submitting}>
Submit
</button>
<button
type="button"
onClick={form.reset}
disabled={submitting || pristine}
>
Reset
</button>
</div>
<pre>{JSON.stringify(values, 0, 2)}</pre>
</form>
)}
/>
</Styles>
);
render(<App />, document.getElementById("root"));
Styled.js
import styled, { css } from 'styled-components'
const btn = (light, dark) => css`
white-space: nowrap;
display: inline-block;
border-radius: 5px;
padding: 5px 15px;
font-size: 16px;
color: white;
&:visited {
color: white;
}
background-image: linear-gradient(${light}, ${dark});
border: 1px solid ${dark};
&:hover {
background-image: linear-gradient(${light}, ${dark});
&[disabled] {
background-image: linear-gradient(${light}, ${dark});
}
}
&:visited {
color: black;
}
&[disabled] {
opacity: 0.6;
cursor: not-allowed;
}
`
const btnDefault = css`
${btn('#ffffff', '#d5d5d5')} color: #555;
`
const btnPrimary = btn('#4f93ce', '#285f8f')
export default styled.div`
font-family: sans-serif;
h1 {
text-align: center;
color: #222;
}
h2 {
text-align: center;
color: #222;
}
& > div {
text-align: center;
}
a {
display: block;
text-align: center;
color: #222;
}
form {
max-width: 500px;
margin: 10px auto;
border: 1px solid #ccc;
padding: 20px;
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
border-radius: 3px;
& > div {
display: flex;
flex-flow: row nowrap;
line-height: 2em;
margin: 5px;
& > label {
color: #333;
width: 110px;
font-size: 1em;
line-height: 32px;
}
& > input,
& > select,
& > textarea {
flex: 1;
padding: 3px 5px;
font-size: 1em;
margin-left: 15px;
border: 1px solid #ccc;
border-radius: 3px;
}
& > input[type='checkbox'] {
margin-top: 7px;
}
& > div {
margin-left: 16px;
& > label {
display: block;
& > input {
margin-right: 3px;
}
}
}
& > span {
line-height: 32px;
margin-left: 10px;
color: #800;
font-weight: bold;
}
}
& > .buttons {
display: flex;
flex-flow: row nowrap;
justify-content: center;
margin-top: 15px;
}
button {
margin: 0 10px;
&[type='submit'] {
${btnPrimary};
}
&[type='button'] {
${btnDefault};
}
}
pre {
border: 1px solid #ccc;
background: rgba(0, 0, 0, 0.1);
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
padding: 20px;
}
}
`
沙盒Link https://codesandbox.io/s/link-in-react-final-form-z2g2b?fontsize=14&hidenavigation=1&theme=dark
哇!这是一个有趣的。错误是将 link 从鼠标光标下移出,因此当您 "mouse up" 完成单击时,鼠标不再位于 hyperlink.
上方如果您按住鼠标按钮然后在释放之前将其移动到跟随 link,则 link 将 "work"。
可以通过将错误设置为 space 来修复它是否显示,这样它就不会将页面的其余部分向下移动。
严格回答问题:
touched && error ?
<span style={{ color: "red" }}>{error}</span> :
<span> </span>
当您进出场时,这也将消除场的不断移动。
还有其他选项:
- 将必填项放在字段末尾,就像密码字段一样
- 仅在提交时验证
- 将错误显示为工具提示
- 在渲染前使用短暂的超时