怎么做一个缓缓变大,还能缓缓变小的提示栏--P2 自动聚焦

上一篇就是简单介绍了我是如何编写一个带有渐入渐出动画效果的input框的实现细节。
我当时觉得很高兴,因为我对这种(对我的技术力来说已经是比较)酷炫的动画一直没有特别好的理解和使用,兴奋之余,发现网上也没找到类似的东西,就给贴上网了。

然后就继续完善Input的,过程中又发现一个问题。

我的Input不能自动聚焦。

下面贴图示意。
能自动聚焦

不能自动聚焦,弱鸡

上面两张图片说明了我的需求,这个Input框出现了,说明用户要输入东西了,那么为了交互体验,势必要自动聚焦,在react中,这个需要一个小技巧。
有三个小点
1.在input元素上添加 autoFocus,不好用。
这个貌似是react给input加上focus效果的时间比react把input渲染到DOM里的时间早,所以失效。
2.使用useEffect/useLayoutEffect,不一定好用
这个我试了,实际上他是生效的.但是input从invisible到visible 有一个re-render,这个re-render把之前的focus效果给“顶掉了”
3.在 useEffect/useLayoutEffect里加上一个 setTimeout,就有效了。
实际上就是做一个延迟更大的 useEffect 。

程序文本如下

import React, { ReactElement } from "react";
import cs from "classnames";

import ButtonCustomized from "../../../../lib/Button/ButtonCustomized/ButtonCutomized";
interface Props {}

export default function RollingInput({}: Props): ReactElement {
  // 开合状态的state
  const [state, setstate] = React.useState(false);
  //input value的状态
  const [val, setval] = React.useState("");
  let inputRef = React.useRef(null);
  // 注意, 即使是useLayoutEffect ,自动focus也失效.
  //用setTimeout做个更慢的延迟。。
  React.useEffect(() => {
    setTimeout(() => {
      (inputRef.current as any).focus();
    }, 100);
    (inputRef.current as any).focus();
    return () => {
      // can this clear operation work? will it cause any trouble?
      inputRef = null as unknown as React.MutableRefObject<null>;
    };
  }, [state]);
  return (
    <div className="tw-relative">
      <div
        className={cs("tw-absolute  tw-w-4/5 tw-transition-all ", {
          "tw-pt-0": state === false,
          "tw-pt-4": state,
          "tw-h-0": state === false,
          "tw-duration-300": state,
        })}
      >
        <div
          className={cs("-tw-mt-4 tw-flex tw-duration-100", {
            // "tw-invisible": !state,
          })}
        >
          <input
            className="tw-caret-purple-800
            tw-rounded-l-md
            tw-outline-none
            tw-leading-[3.5rem]
            tw-text-4xl
            tw-pl-3
            tw-align-middle
            tw-h-14
            tw-text-black tw-w-4/5 
            
            tw-z-30"
            type="text"
            value={val}
            ref={inputRef}
            onChange={(e) => {
              e.preventDefault();
              setval(e.target.value);
            }}
            autoFocus
          />

          <ButtonCustomized
            color="primary"
            onClick={() => {
              setstate(!state);
            }}
            height={3.5}
            width={6}
          >
            提交
          </ButtonCustomized>
        </div>
      </div>

      <div
        className="tw-h-16 tw-w-4/5 tw-bg-orange-500"
        onClick={() => {
          setstate(!state);
        }}
      >
        在这里添加任务
      </div>
    </div>
  );
}

posted @ 2023-02-04 23:42  刘老六  阅读(22)  评论(0编辑  收藏  举报