【问题标题】:React Native - focus the first touchable in a listReact Native - 关注列表中的第一个可触摸对象
【发布时间】:2021-08-30 23:07:45
【问题描述】:

我试图让FlatList 中的第一个TouchableOpacity 在渲染后获得焦点。我尝试使用引用并从useEffect 触发焦点,但我无法弄清楚。

代码如下:

import React, {useRef, useEffect} from "react";
import {FlatList, Text, TouchableOpacity, View} from "react-native";

const MyScreen = () => {
    const refs = useRef([]);

    useEffect (() => {
        refs.current[0].focus()
    }, []);

    const setFocusedElement = (element) => {
        console.log(element);
    }

    return (
        <View>
            <FlatList
                data={[1, 2, 3]}
                keyExtractor={(item) => item}
                renderItem={({ item, index }) => {
                    return (
                        <TouchableOpacity ref={el => refs.current[index] = el} onFocus={() => setFocusedElement(item)}>
                            <View><Text>{item}</Text></View>
                        </TouchableOpacity>
                    );
                }}
            />
        </View>
    );
}

export default MyScreen;

我收到类似这样的错误:“TypeError: undefined is not an object (evalating 'refs.current[0].focus')”

[EDIT] 在基于@drew-reese 很好的答案进行了小幅编辑后,参考工作正常,但焦点仍然没有。

[EDIT 2] 下面是这个问题的一个简单示例:https://snack.expo.dev/@jerrybels/calm-ramen

【问题讨论】:

    标签: reactjs react-native


    【解决方案1】:

    refs 本身是一个 React 引用,但您似乎没有正确地按索引设置子引用。您仍然应该引用 refs.current 来更新 ref 值。

    ref={el => refs.current[index] = el}
    

    您可能会发现为每个正在渲染的子组件显式创建 ref 并将这些 as 传递给 ref 比使用回调语法更好。

    const refs = useRef([]);
    
    refs.current = data.map((_, i) => refs.current[i] ?? createRef());
    
    useEffect (() => {
      refs.current[0].current.focus();
    }, []);
    
    ...
    
    <FlatList
      data={data}
      keyExtractor={(item) => item}
      renderItem={({ item, index }) => (
        <TouchableOpacity ref={refs.current[index]}>
          <View><Text>{item}</Text></View>
        </TouchableOpacity>
      )}
    />
    

    【讨论】:

    • @JeremyBelolo 函数体中的refs.current 应该为“data”数组中的每个元素生成引用。这会在每个渲染周期中发生,它映射“数据”并在新的 ref 不存在时创建它们,否则使用之前生成的 ref。如果data 是异步加载的,那么您不想使用空的依赖数组,您需要将“数据”添加为依赖。为了防止空访问,您可以使用可选链接,即refs.current[0]?.focus();。您能否提供一个更准确的代码示例来代表您的用例?
    • 我会尝试您的建议并在需要时提供更准确的示例,谢谢!
    • @JeremyBelolo 试试snack.expo.dev/@drew.w.reese/calm-ramen。它修复了设置 refs 并专注于数组中的第一个元素而不是第二个。
    • @JeremyBelolo 欢迎。我的回答是否充分解决/解决了您当前发布的问题/问题?
    • @JeremyBelolo 好的,谢谢。我会看看你的新帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 2018-11-29
    • 2019-05-22
    • 2021-11-08
    相关资源
    最近更新 更多