React中如何禁用页面首次render时textarea的autofocus?
解决首次渲染时textarea自动聚焦引发页面滚动的问题
嘿,我完全懂你这个困扰——首次渲染时带autoFocus的textarea会直接把页面扯到底部,但点击按钮打开textarea时又需要它能正常获得焦点。别担心,咱们可以通过手动控制聚焦时机来搞定这个矛盾,不用依赖原生的autoFocus属性。
具体实现步骤
第一步:移除原生
autoFocus属性
先把textarea上的autoFocus删掉,彻底避免首次渲染时自动触发聚焦行为。第二步:用React的
useRef和状态控制聚焦时机
我们需要区分「首次渲染」和「按钮触发的渲染」两个场景,只在按钮点击后让textarea获得焦点:- 创建一个ref指向textarea元素:
const textareaRef = useRef(null); - 添加一个状态标记是否需要触发聚焦(仅在按钮点击时设为
true):const [shouldFocusTextarea, setShouldFocusTextarea] = useState(false); - 在按钮点击事件里,打开textarea的同时更新状态:
const handleOpenTextarea = () => { // 你的打开textarea的业务逻辑 setShouldFocusTextarea(true); }; - 用
useEffect监听状态变化,仅当需要聚焦时执行focus操作:useEffect(() => { if (shouldFocusTextarea && textareaRef.current) { textareaRef.current.focus(); // 聚焦后重置状态,避免重复触发 setShouldFocusTextarea(false); } }, [shouldFocusTextarea]);
- 创建一个ref指向textarea元素:
第三步:更新textarea组件代码
把ref绑定到textarea上,最终代码如下:<textarea type="textarea" className={`ostalo-txt ${ isOstalo ? 'left-radius-0' : 'left-radius-0 ostalo-quantity'} ${ item.name === "Ostalo" ? 'ostalo-txt-area' : ''}`} name={`ostaloVsadek`} onChange={(e)=>handleChange(e, item)} value={textAreaValue(item).toString()} data-idx={idx} disabled={!editable} ref={textareaRef} />
为什么这个方案有效?
原生autoFocus会在组件挂载时立即触发聚焦,浏览器为了让聚焦元素可见会自动滚动页面。而我们手动控制的聚焦逻辑,只在按钮点击后才执行,首次渲染时不会触发focus(),自然就不会导致页面滚动,同时也保留了按钮点击后textarea获得焦点的需求。
如果是列表中的多个textarea场景,只需要把ref和状态改成对应每个item的独立存储即可(比如用对象或数组来管理每个item的ref和聚焦状态)。
内容的提问来源于stack exchange,提问作者pecvari
相关产品推荐
相关产品推荐

