设置状态的React Native重用函数

时间:2019-02-23 22:21:19

标签: reactjs react-native redux react-redux setstate

我是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不是函数

2 个答案:

答案 0 :(得分:1)

您可以做两件事来使其工作

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

答案 1 :(得分:0)

您需要从组件内部调用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