Упростите этот повторяющийся шаблон кода для компонентов класса - PullRequest
0 голосов
/ 04 августа 2020

В настоящее время я реализую поддержку специальных возможностей (VoiceOver / Talkback) для своего приложения, и я довольно часто использую AccessibilityInfo.setAccessibilityFocus ( см. Официальные документы ), для чего требуется responseTag, который я могу получить только используя findNodeHandle согласно этот ответ .

Это означает, что я продолжаю повторять один и тот же шаблон, включающий довольно много вызовов функций, снова и снова для многих различных компонентов. Первоначально я пытался переместить сохраненные ссылки и вызов, чтобы установить фокус на мой диспетчер состояний (в данном случае используя MobX), но в итоге я получил много неудачных вызовов findNodeHandle, потому что иногда компонент был отключен до того, как был сделан вызов.

Это суть того, что я повторяю:

import React, {Component} from 'react'
import {
  ...
  findNodeHandle,
  AccessibilityInfo
  ...
} from 'react-native';

class Sample extends React.Component {
    constructor(props) {
        super(props)
        this.accessibilityRef = null;
    }

    ...

    componentDidMount() {
        this.setAccessibilityFocus()
    }

    componentDidUpdate() {
        this.setAccessibilityFocus()
    }

    setAccessibilityRef(el) {
        this.accessibilityRef = el
    }

    setAccessibilityFocus() {
        if (this.accessibilityRef) {
            const reactTag = findNodeHandle(this.accessibilityRef);
            AccessibilityInfo.setAccessibilityFocus(reactTag);
        }
    }

    render() {
        return (
            <View ref={this.setAccessibilityRef} accessible={true}>
                ...
            </View>
        )
    }
}

Можно ли как-то сделать из этого что-то многоразовое? Может быть, декоратор или как расширение класса, чтобы я мог его повторно использовать?

1 Ответ

1 голос
/ 04 августа 2020

Да, вы можете ...

Пусть, SampleWrapper.js - ваша оболочка.

import React, {Component} from 'react'
import {
  ...
  findNodeHandle,
  AccessibilityInfo
  ...
} from 'react-native';

export default class SampleWrapper extends Component {
    constructor(props) {
        super(props)
        this.accessibilityRef = null;
    }

    ...

    componentDidMount() {
        this.setAccessibilityFocus()
    }

    componentDidUpdate() {
        this.setAccessibilityFocus()
    }

    setAccessibilityRef(el) {
        this.accessibilityRef = el
    }

    setAccessibilityFocus() {
        if (this.accessibilityRef) {
            const reactTag = findNodeHandle(this.accessibilityRef);
            AccessibilityInfo.setAccessibilityFocus(reactTag);
        }
    }

    render() {
        return (
            <View ref={this.setAccessibilityRef} accessible={true}>
                {this.props.children}
            </View>
        )
    }
}

Теперь предположим, что вы хотите использовать указанную выше оболочку в своей Sample.js

import React, {Component} from 'react'
import SampleWrapper from './path/to/SampleWrapper'

class Sample extends Component {
    constructor(props) {
        super(props)
    }

    render() {
        return (
            <SampleWrapper>
                ....
            </SampleWrapper>
        )
    }
}

Вы можете поставить ref s, а затем вы можете управлять им, как вы ожидаете.

PS: Я не тестировал это перед публикацией. Надеюсь, это сработает и поможет вам. Если у вас возникли проблемы с этим ответом или если вы хотите добавить что-то еще и сомневаетесь, как это сделать, просто прокомментируйте это здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...