设置状态的 React Native 重用函数
React Native reuse function that sets state
我是 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 吗?到目前为止,我找不到关于 SO 的明确答案。
更新:我也试过了
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 不是函数
您需要从组件中调用 this.setState
。你不能只是从任何地方打电话。
您的辅助函数未绑定到您的 class。请注意,原来的 var that = this
设置为 that.setState
将在 then
块内工作。在您的原始示例中,checkUserExists
很可能是使用 https://github.com/tc39/proposal-class-fields 绑定的。现在您已经有了一个常规(未绑定到 class)函数,它无法访问 this
或其任何方法,包括 setState
.
老实说,这是一个 XY 问题,恕我直言。如果你想提取一个辅助函数,你应该让它 return 你需要的数据,而不是试图传递对 class 你想要更新其状态的引用。您应该只 return 组件的数据——您必须这样做,因为无论如何您的数据库调用都是异步的——并在组件中使用该数据来调用它自己的 setState
方法。
你可以做两件事来让它发挥作用
- 将.then函数改成箭头函数或绑定
- 在 class 上下文中调用
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
})
}
}
我是 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 吗?到目前为止,我找不到关于 SO 的明确答案。
更新:我也试过了
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 不是函数
您需要从组件中调用 this.setState
。你不能只是从任何地方打电话。
您的辅助函数未绑定到您的 class。请注意,原来的 var that = this
设置为 that.setState
将在 then
块内工作。在您的原始示例中,checkUserExists
很可能是使用 https://github.com/tc39/proposal-class-fields 绑定的。现在您已经有了一个常规(未绑定到 class)函数,它无法访问 this
或其任何方法,包括 setState
.
老实说,这是一个 XY 问题,恕我直言。如果你想提取一个辅助函数,你应该让它 return 你需要的数据,而不是试图传递对 class 你想要更新其状态的引用。您应该只 return 组件的数据——您必须这样做,因为无论如何您的数据库调用都是异步的——并在组件中使用该数据来调用它自己的 setState
方法。
你可以做两件事来让它发挥作用
- 将.then函数改成箭头函数或绑定
- 在 class 上下文中调用
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
})
}
}