问题描述
有固定数量的设置决定组件是否应该可见,即:
There's a fixed number of settings that determine whether the component should be visible, i.e.:
const restrictions = {
isLogged: true, // TRUE stands for: check if the condition is met
hasMoney: true,
didWinYesterday: false,
}
对于每个 restrictions
键,我用 useState
创建了一个状态,并用 false
初始化它们,例如:
For each restrictions
key, I've created a state with useState
and initialized them all with false
, like:
const [isUserLogged, setIsUserLogged] = useState(false)
const [hasUserMoney, setHasUserMoney] = useState(false)
const [didUserWinYday, setDidUserWinYday] = useState(false)
接下来,我使用 useEffect
检查每个条件并相应地更新状态:
Next, I am checking against each condition with useEffect
and updating the state accordingly:
useEffect(() => {
const checkIfUserIsLogged = async () => {
// calling an API to get boolean
const isLogged = await API.call()
setIsUserLogged(isLogged)
}
// If the restriction is set to false, ignore checking and set relevant state
if (!restrictions.isLogged) {
setIsUserLogged(true)
return
}
checkIfUserIsLogged()
}, [restrictions.isLogged])
最后,我正在检查我是否应该渲染实际组件或者我应该像这样提前中断:
Finally, I am checking if I should render the actual component or should I break early like so:
if (!isUserLogged) return <p>User not logged in.</p>
useEffect
代码和上面的检查一共重复了 3 次.每次重复都在进行不同的 API 调用并更新不同的状态,但整体结构保持不变.我希望我能做得更干,但不知道如何开始.欢迎任何提示,谢谢!
The useEffect
code and the check above is repeated 3 times in total. Each of the repetition is making different API call and is updating different state, but the overall structure stays the same.I wish I could do it more DRY but not sure how to get started. Any tips are welcome, thanks!
推荐答案
我会将单个原子重构为一个自定义的 useRestrictionState
原子,该原子在内部处理效果:
I'd refactor a single atom into a custom useRestrictionState
atom that internally deals with the effect:
const restrictions = {
isLogged: true, // TRUE stands for: check if the condition is met
hasMoney: true,
didWinYesterday: false,
};
function useRestrictionState(restrictionFlag, apiFunc) {
const [flag, setFlag] = React.useState(undefined);
useEffect(() => {
if (!restrictionFlag) {
setFlag(true);
} else {
apiFunc().then((result) => setFlag(result));
}
}, [restrictionFlag]);
return flag;
}
function Component() {
const isUserLogged = useRestrictionState(restrictions.isLogged, getLoginState);
const hasUserMoney = useRestrictionState(restrictions.hasMoney, getUserMoney);
const didUserWinYday = useRestrictionState(restrictions.didWinYesterday, getUserDidWinYesterday);
}
如果您总是需要所有这些,您可以自然地将其包装在另一个自定义钩子中:
If you always need all of them, you can naturally wrap this in another custom hook:
function useUserRestrictionState(restrictions) {
const isUserLogged = useRestrictionState(restrictions.isLogged, getLoginState);
const hasUserMoney = useRestrictionState(restrictions.hasMoney, getUserMoney);
const didUserWinYday = useRestrictionState(restrictions.didWinYesterday, getUserDidWinYesterday);
return { isUserLogged, hasUserMoney, didUserWinYday };
}
function Component() {
const { isUserLogged, hasUserMoney, didUserWinYday } = useUserRestrictionState(restrictions);
}
这篇关于使用 React 钩子的冗余代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!