You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Web/Expo中如何为Pressable模拟focus-visible效果

问题1解决方案:点击后自动清除focused状态

直接在onPress回调中主动让当前聚焦的DOM元素失焦即可,需要加端判断避免Native端运行报错:

import { Platform } from 'react-native';

<Pressable 
  onPress={() => {
    if (Platform.OS === 'web') {
      document.activeElement.blur();
    }
    // 此处可追加原有业务逻辑
  }}
  style={({pressed, hovered, focused}) => [
      {
        backgroundColor: pressed ? "orange" : hovered ? "green" : focused ? "red" : "lightgray", 
        padding: 20 
      }
]}>
    {
      ({pressed, hovered, focused}) => (
        <Text>
          {pressed ? "Pressed" : hovered ? "Hovered" : focused ? "Focused" : "Default"}
        </Text>
      )
    }
</Pressable>

点击后元素会立即失焦,focused状态自动变为false,样式回到默认的浅灰色。


问题2解决方案:手动实现focus-visible效果

如果不想破坏默认聚焦行为,只需要区分「键盘触发的聚焦」和「鼠标点击触发的聚焦」,可以通过监听全局输入事件维护输入类型状态,结合Pressable的focused状态判断应用哪套样式:

import { useState, useEffect } from 'react';
import { Platform, Pressable, Text } from 'react-native';

const FocusVisiblePressable = () => {
  // 标记当前聚焦是否来自键盘操作
  const [isKeyboardTrigger, setIsKeyboardTrigger] = useState(false);

  useEffect(() => {
    // 仅web端需要监听事件
    if (Platform.OS !== 'web') return;

    // 按下Tab键时标记为键盘操作
    const handleKeyDown = (e) => e.key === 'Tab' && setIsKeyboardTrigger(true);
    // 鼠标/触摸操作时标记为非键盘操作
    const handlePointerDown = () => setIsKeyboardTrigger(false);

    window.addEventListener('keydown', handleKeyDown);
    window.addEventListener('pointerdown', handlePointerDown);
    return () => {
      window.removeEventListener('keydown', handleKeyDown);
      window.removeEventListener('pointerdown', handlePointerDown);
    };
  }, []);

  return (
    <Pressable 
      style={({pressed, hovered, focused}) => [
        {
          padding: 20,
          // 仅键盘触发的聚焦才显示聚焦样式
          backgroundColor: pressed ? "orange" : hovered ? "green" : (focused && isKeyboardTrigger) ? "red" : "lightgray", 
        }
      ]}
    >
      {
        ({pressed, hovered, focused}) => (
          <Text>
            {pressed ? "Pressed" : hovered ? "Hovered" : (focused && isKeyboardTrigger) ? "Focused" : "Default"}
          </Text>
        )
      }
    </Pressable>
  )
}

如果需要多组件复用,可以把事件监听的逻辑抽成自定义Hook,全局共享输入类型状态即可。

内容的提问来源于stack exchange,提问作者wongx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 14:24:03