Реагируйте на функцию повторного использования Native, которая устанавливает состояние - PullRequest
0 голосов
/ 24 февраля 2019

Я новичок в React Native.В моем приложении одна и та же функция проверки наличия пользователя в базе данных используется в 3 разных файлах.

checkUserExists = (userId) => {
        var that = this;
        database.ref('users').child(userId).once('value').then(function(result){
        const exists = (result.val() !== null);

        if (exists) {
            var data = result.val();
            that.setState({
                username: data.username,
                name: data.name
            })
        }
    })
}

Чтобы уменьшить объем кода, я хочу поместить эту функцию в компонент, чтобы она моглабыть повторно использованы.Поэтому я создал новый файл с этой функцией:

export function checkUserExists (userId) {
    database.ref('users').child(userId).once('value').then(function(result){
        const exists = (result.val() !== null);

        if (exists) {
            var data = result.val();
            setState({
                username: data.username,
                name: data.name
            })
        }
    })
}

Но это встречается с [Отклонение необработанного обещания: ReferenceError: Невозможно найти переменную: setState]

Как правильно обращаться с этим?Должен ли я использовать Redux?Я не могу найти четкий ответ по ТАК до сих пор.

Обновление: я также пытался

export default class Authentication extends Component {
    checkUserExists = (userId) => {
        database.ref('users').child(userId).once('value').then(function(result){
            const exists = (result.val() !== null);

            if (exists) {
                var data = result.val();
                setState({
                    username: data.username,
                    name: data.name
                })
            }
        })
    }
}

, и я пытался назвать его как

Authentication.checkUserExists(user.id);

, но получает: TypeError: _authentication.default.checkUserExists isне функция

Ответы [ 2 ]

0 голосов
/ 24 февраля 2019

Две вещи, которые вы можете сделать, чтобы заставить его работать

  1. Измените функцию .then на функцию стрелки или свяжите ее
  2. Вызовите функцию checkUserExists, когда вы выполняете ее с помощьюконтекст класса
 export function checkUserExists (userId) {
        database.ref('users').child(userId).once('value').then((result) => {
            const exists = (result.val() !== null);

            if (exists) {
                var data = result.val();
                this.setState({
                    username: data.username,
                    name: data.name
                })
            }
        })
    }

Теперь, когда вы хотите использовать checkUserExists, вы можете использовать его с .call как

checkUserExists.call(this, userId);

Один недостаток этого решения, хотя это то, что это может бытьтрудно отладить ваше приложение, так как состояние устанавливается из кода, находящегося вне компонента

Чтобы преодолеть недостатки, вы можете определить свой метод как

export async function checkUserExists (userId) {
      try {
        const result = await database.ref('users').child(userId).once('value');
        const exists = (result.val() !== null);
        if (exists) {
            return data;
        }
        return false;
      } catch(e) {
         console.log(e);

      }
  }

и в компоненте использовать егокак

someFunc = async () => {
   const data = await checkUserExists(userId);
   if (data) {
        this.setState({
            username: data.username,
            name: data.name
        })
   }
}
0 голосов
/ 24 февраля 2019

Вам необходимо позвонить this.setState из компонента.Вы не можете просто позвонить, если откуда угодно.

Ваша вспомогательная функция не связана с вашим классом.В оригинале var that = this указано, что that.setState будет работать из блока then.Вероятно, что checkUserExists связано с использованием https://github.com/tc39/proposal-class-fields в вашем исходном примере.Теперь у вас есть обычная (не привязанная к классу) функция, и она не имеет доступа ни к this, ни к каким-либо из ее методов, включая setState.

Если честно, это XYпроблема, имхоЕсли вы хотите извлечь вспомогательную функцию, вам нужно, чтобы она возвращала нужные вам данные, а не пытаться передавать ссылки на класс, состояние которого вы хотите обновить.Вместо этого вам следует просто вернуть данные компоненту - и вы должны сделать это, потому что ваш вызов базы данных в любом случае асинхронный - и использовать эти данные в компоненте для вызова своего собственного setState метода.

https://reactjs.org/docs/react-component.html#setstate

...