如何使用按键有条件地渲染输入框

How to conditionally render input box with key press

我一直在构建 URL Shortner。所以在前端我试图构建像 Cut.ly 这样的输入框。例如,一开始,我会有一个带有缩短按钮的空输入框。当我 post 一个 Long URL 并按下提交时,它将有条件地呈现另一个输入框,其中包含一个带有复制按钮的短 URL。我已经实现了这个逻辑。现在我想做的是在 Short URL 输入框中,每当我按下任何按键时,它都会使用 Shorten 按钮呈现输入框。那么,我该如何实现这个逻辑呢?作为参考,我正在 post 播放演示视频。

到目前为止,这是我的代码。我正在使用 React Hook Form 进行表单管理。

const CreateUrl = ({ match }) => {
  const [shortUrl] = useState('https://cutt.ly/wUBnKby');
  const [isSubmitted, setIsSubmitted] = useState(false);
  const {
    register,
    handleSubmit,
    reset,
    formState: { errors },
  } = useForm({
    criteriaMode: 'all',
    mode: 'onChange',
  });

  const onSubmit = (data) => {
    console.log(data);
    reset('', {
      keepValues: false,
    });
    setIsSubmitted(true);
  };
  return (
    <div className="create__url">
      <Row>
        <Colxx xxs="12">
          <Breadcrumb heading="menu.createUrl" match={match} />
          <Separator className="mb-5" />
        </Colxx>
      </Row>
      <Row>
        <Colxx xxs="12" mt="4">
          {!isSubmitted ? (
            <form onSubmit={handleSubmit(onSubmit)}>
              <Row>
                <Colxx xs="12" lg="8">
                  <fieldset>
                    <input
                      name="url"
                      type="text"
                      placeholder="Paste long Url and Shorten it"
                      {...register('url', {
                        required: 'Url is Required',
                        pattern: {
                          value:
                            /[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/i,
                          message: 'Please enter a valid Url',
                        },
                      })}
                    />
                    <ErrorMessage
                      errors={errors}
                      name="url"
                      render={({ messages }) =>
                        messages
                          ? Object.entries(messages).map(([type, message]) => (
                              <p className="error__message" key={type}>
                                <AiFillWarning style={{ marginTop: '-5px' }} />
                                <span>{message}</span>
                              </p>
                            ))
                          : null
                      }
                    />
                  </fieldset>
                </Colxx>
                <Colxx xs="12" lg="4">
                  <Button size="lg" type="submit">
                    {' '}
                    Submit
                  </Button>
                </Colxx>
              </Row>
            </form>
          ) : (
            <form>
              <Row>
                <Colxx xxs="12" lg="8">
                  <fieldset>
                    <input name="url" type="text" defaultValue={shortUrl} />
                  </fieldset>
                </Colxx>
                <Colxx xs="12" lg="4">
                  <Button size="lg" type="submit">
                    Copy
                  </Button>
                </Colxx>
              </Row>
            </form>
          )}
        </Colxx>
      </Row>
     </div>
  );
}

这里可以使用一个空数组来存储缩短的URLs。当您按下缩短 URL 按钮时,使该输入字段的状态为真,并使用该数组在该字段中显示文本。我在我的 Shortly 网站上实现了同样的功能。您可以访问它以查看演示 Shortly 我的 GitHub 仓库有这个网站的完整源代码。那会对你有很大帮助—— 我的 GitRepo 希望我能解决你的疑惑......

我已经解决了这个逻辑。我什至在 shortUrl 输入框上放置了一个 onKeyUp,然后使用 useState 跟踪按键事件。这是代码 -

const CreateUrl = ({ match }) => {
  const [shortUrl, setShortUrl] = useState('');
  const [isSubmitted, setIsSubmitted] = useState(false);
  const [isKeyPressed, setIsKeyPressed] = useState(false);
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    criteriaMode: 'all',
    mode: 'onChange',
  });

  const onSubmit = (data) => {
    console.log(data);
    setIsSubmitted(true);
    setIsKeyPressed(false);
    setShortUrl('https://cutt.ly/wUBnKby');
  };

  return (
    <div className="create__url">
      <Row>
        <Colxx xxs="12">
          <Breadcrumb heading="menu.createUrl" match={match} />
          <Separator className="mb-5" />
        </Colxx>
      </Row>
      <Row>
        <Colxx xxs="12" mt="4">
          {!isSubmitted || isKeyPressed ? (
            <form onSubmit={handleSubmit(onSubmit)}>
              <Row>
                <Colxx xs="12" lg="8">
                  <fieldset>
                    <input
                      name="url"
                      type="text"
                      placeholder="Paste long Url and Shorten it"
                      {...register('url', {
                        required: 'Url is Required',
                        pattern: {
                          value:
                            /[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/i,
                          message: 'Please enter a valid Url',
                        },
                      })}
                    />
                    <ErrorMessage
                      errors={errors}
                      name="url"
                      render={({ messages }) =>
                        messages
                          ? Object.entries(messages).map(([type, message]) => (
                              <p className="error__message" key={type}>
                                <AiFillWarning style={{ marginTop: '-5px' }} />
                                <span>{message}</span>
                              </p>
                            ))
                          : null
                      }
                    />
                  </fieldset>
                </Colxx>
                <Colxx xs="12" lg="4">
                  <Button size="lg" type="submit">
                    {' '}
                    Submit
                  </Button>
                </Colxx>
              </Row>
            </form>
          ) : (
            <form>
              <Row>
                <Colxx xxs="12" lg="8">
                  <fieldset>
                    <input
                      name="url"
                      type="text"
                      value={shortUrl}
                      onKeyUp={() => setIsKeyPressed(true)}
                    />
                  </fieldset>
                </Colxx>
                <Colxx xs="12" lg="4">
                  <Button size="lg" type="submit">
                    Copy
                  </Button>
                </Colxx>
              </Row>
            </form>
          )}
        </Colxx>
      </Row>
      {/* <Row className="mt-4">
        <Colxx xxs="12">
          {isSubmitted && (
       
          )}
        </Colxx>
      </Row> */}
    </div>
  );
};