ReactJS 中的私有路由条件运算符
Private Route Conditional Operator in ReactJS
似乎是个小问题。
我有一个应用程序,人们可以在其中通过“条纹”进行订阅。想根据订阅授予对几个 URL 的访问权限,否则将它们带回“个人资料”页面。
有些东西不工作。
获取 订阅 的 Firebase 查询未给出订阅结果。不知何故 onSnapShot 没有获取任何东西。可能是因为在页面渲染开始时 UID 为 null。
打开的条件运算符无效。不确定这个问题是什么。
function PaidRoutes(props) {
const [subscription, setSubscription] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
const unsub = auth.onAuthStateChanged((authObject) => {
unsub();
if (authObject) {
setLoading(true);
const uid = auth.currentUser?.uid;
console.log('UID ==>', uid);
let docRef = query(collection(db, 'customers', uid, 'subscription'));
console.log('DOC REF ==> ', docRef);
onSnapshot(docRef, (snap) => {
snap.forEach((doc) => {
console.log('Role of Subscription', doc.data().role);
setSubscription(doc.data().role);
});
});
} else {
console.log('not logged in');
setLoading(false);
}
});
return () => {
unsub();
};
}, []);
return (
<Route
{...props}
render={(props) =>
subscription ? (
<Component {...props} />
) : (
<Redirect to='/profileScreen' />
)
}
/>
);
感谢德鲁的评论。 react-router-dom安装的版本是5.2.0
问题
我在 PaidRoute
代码中看到的潜在问题:
- 在身份验证状态处理程序中调用取消订阅函数,这可能允许身份验证检查在初始身份验证更改时工作一次,但随后将自行取消订阅并停止工作,直到组件重新安装。
loading
状态最初是 false
,因此在初始渲染时基于它的任何检查都不会执行您想要的操作。 loading
也不用于推迟条件渲染。
subscription
状态最初是一个空数组,它仍然是真实的,因此无论任何身份验证状态如何,检查它的条件逻辑都可能允许访问受保护的路由。
解决方案
- 不要取消订阅回调中的身份验证更改侦听器。
- 从
loading
开始处理初始渲染周期。有条件地呈现 null 或一些加载指示器。
- 从空
subscription
状态开始。
代码:
function PaidRoutes(props) {
const [subscription, setSubscription] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((authObject) => {
if (authObject) {
setLoading(true);
const uid = auth.currentUser?.uid;
console.log('UID ==>', uid);
const docRef = query(collection(db, 'customers', uid, 'subscription'));
console.log('DOC REF ==> ', docRef);
onSnapshot(docRef, (snap) => {
snap.forEach((doc) => {
console.log('Role of Subscription', doc.data().role);
setSubscription(doc.data().role);
});
});
} else {
console.log('not logged in');
setSubscription(null); // <-- reset auth state
}
setLoading(false); // <-- clear loading state outside if-else
});
return unsubscribe;
}, []);
if (loading) {
return null; // or loading indicator, spinner, etc...
}
return subscription ? (
<Route {...props} />
) : (
<Redirect to='/profileScreen' />
);
}
似乎是个小问题。
我有一个应用程序,人们可以在其中通过“条纹”进行订阅。想根据订阅授予对几个 URL 的访问权限,否则将它们带回“个人资料”页面。
有些东西不工作。
获取 订阅 的 Firebase 查询未给出订阅结果。不知何故 onSnapShot 没有获取任何东西。可能是因为在页面渲染开始时 UID 为 null。
打开的条件运算符无效。不确定这个问题是什么。
function PaidRoutes(props) {
const [subscription, setSubscription] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
const unsub = auth.onAuthStateChanged((authObject) => {
unsub();
if (authObject) {
setLoading(true);
const uid = auth.currentUser?.uid;
console.log('UID ==>', uid);
let docRef = query(collection(db, 'customers', uid, 'subscription'));
console.log('DOC REF ==> ', docRef);
onSnapshot(docRef, (snap) => {
snap.forEach((doc) => {
console.log('Role of Subscription', doc.data().role);
setSubscription(doc.data().role);
});
});
} else {
console.log('not logged in');
setLoading(false);
}
});
return () => {
unsub();
};
}, []);
return (
<Route
{...props}
render={(props) =>
subscription ? (
<Component {...props} />
) : (
<Redirect to='/profileScreen' />
)
}
/>
);
感谢德鲁的评论。 react-router-dom安装的版本是5.2.0
问题
我在 PaidRoute
代码中看到的潜在问题:
- 在身份验证状态处理程序中调用取消订阅函数,这可能允许身份验证检查在初始身份验证更改时工作一次,但随后将自行取消订阅并停止工作,直到组件重新安装。
loading
状态最初是false
,因此在初始渲染时基于它的任何检查都不会执行您想要的操作。loading
也不用于推迟条件渲染。subscription
状态最初是一个空数组,它仍然是真实的,因此无论任何身份验证状态如何,检查它的条件逻辑都可能允许访问受保护的路由。
解决方案
- 不要取消订阅回调中的身份验证更改侦听器。
- 从
loading
开始处理初始渲染周期。有条件地呈现 null 或一些加载指示器。 - 从空
subscription
状态开始。
代码:
function PaidRoutes(props) {
const [subscription, setSubscription] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((authObject) => {
if (authObject) {
setLoading(true);
const uid = auth.currentUser?.uid;
console.log('UID ==>', uid);
const docRef = query(collection(db, 'customers', uid, 'subscription'));
console.log('DOC REF ==> ', docRef);
onSnapshot(docRef, (snap) => {
snap.forEach((doc) => {
console.log('Role of Subscription', doc.data().role);
setSubscription(doc.data().role);
});
});
} else {
console.log('not logged in');
setSubscription(null); // <-- reset auth state
}
setLoading(false); // <-- clear loading state outside if-else
});
return unsubscribe;
}, []);
if (loading) {
return null; // or loading indicator, spinner, etc...
}
return subscription ? (
<Route {...props} />
) : (
<Redirect to='/profileScreen' />
);
}