React Native Viewpager中的自动焦点输入

问题描述

我正在使用React Native Viewpager来接受用户输入,然后移到下一页按按钮。重要的是要注意,移至下一页是在按下按钮时发生的,而不是通过正常滚动而被禁用的。

我认为处理此问题的最佳方法是在ViewPager上有一个状态,该状态会传播到子项中。

ViewPager.tsx:

export default function ViewPager({ route,navigation }) {

    const ref: React.RefObject<ViewPager> = React.createRef();
    const [currentPage,setCurrentPage] = useState(0);

    let setEntryPage = (page: number) => {
        ref.current?.setPage(page);
        setCurrentPage(page);
    }


    return (
        <View style={{flex: 1}}>
            <ViewPager
                style={styles.viewPager}
                initialPage={0}
                ref={ref}
                scrollEnabled={false}
            >
                {
                    GlobalStuff.map((entry,index) => {
                        return (
                            <Entry
                                key={index}
                                index={index}
                                pagerFocusIndex={currentPage}
                                pagerLength={quizDeck?.litems.length!}
                                setEntryPage={setEntryPage}
                            />
                        )
                    })
                }
            </ViewPager>
        </View>
    );
};

Entry.tsx:

export function Entry(props: EntryProps) {

    const inputRef: React.RefObject<Input> = React.createRef();
    if (props.pagerFocusIndex === props.index) {
        inputRef.current?.focus();
    }

    return (
        <View>
            <Input
                // ...
                ref={inputRef}
            />
            <IconButton
                icon="arrow-right-thick"
                color={colorTheme.green}
                onPress={() => {
                    props.index !== props.pagerLength - 1 ?
                        props.setEntryPage(props.index + 1) :
                        props.navigation!.reset({ index: 0,routes: [{ name: recapScreenName as any }] });
                }}
            />
// ...

不幸的是,inputRef似乎是null,无论如何,可能有更好的方法来实现我要达到的目标。

解决方法

每次渲染组件时,都会调用渲染循环中的所有内容。

    // This is called on every render
    const inputRef: React.RefObject<Input> = React.createRef();
    
    // So is this,it's always null
    if (props.pagerFocusIndex === props.index) {
        inputRef.current?.focus();
    }

将副作用添加到效果中。

    // Untested
    const inputRef = useRef();

    useEffect(() => {
        if (props.pagerFocusIndex === props.index) {
            inputRef.current?.focus();
        }
    },[inputRef.current,props.pagerFocusIndex,props.index]);