Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native reuse function that sets state

I am new to React Native. In my app, the same function to check if user exists in the database is used in 3 different files.

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
            })
        }
    })
}

To reduce amount of code, I want to put this function into a component so that it can be reused. So I created a new file with this function:

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
            })
        }
    })
}

But this is met with [Unhandled promise rejection: ReferenceError: Can't find variable: setState]

What is the proper way to handle this? Do I have to use Redux? I can't find a clear answer on SO so far.

Update: I also tried

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
                })
            }
        })
    }
}

and I tried to call it like

Authentication.checkUserExists(user.id);

but gets: TypeError: _authentication.default.checkUserExists is not a function

like image 770
JAM Avatar asked Nov 27 '25 03:11

JAM


1 Answers

Two things you can do to make it work

  1. Change the .then function to an arrow function or bind it
  2. Call the checkUserExists function where you execute it with the class context
 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
                })
            }
        })
    }

Now where you wanna use checkUserExists, you would use it with .call like

checkUserExists.call(this, userId);

One downside of this solution though is that it might be difficult to debug your app as the state is being set from code that is outside of the component

To overcome the downside you can define your method like

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);

      }
  }

and in the component use it like

someFunc = async () => {
   const data = await checkUserExists(userId);
   if (data) {
        this.setState({
            username: data.username,
            name: data.name
        })
   }
}
like image 84
Shubham Khatri Avatar answered Nov 29 '25 18:11

Shubham Khatri



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!