我当前正在使用react-native-keychain
安全地存储访问令牌。在大多数情况下,此方法运行良好,但是在尝试根据令牌是否可用来有条件地渲染组件时遇到问题。
当前我的代码如下:
function Questionnaire() {
const [token, setToken] = useState(null);
Keychain.getGenericPassword().then(credentials => {
const token = credentials.password.replace('Bearer ', '');
setToken(token);
});
if (token != null) {
return (
<WebView
source={{
uri: `url?token=${token}`,
}}
...
/>
);
} else {
return <Text>Loading...</Text>;
}
}
有条件的渲染在这里起作用,但是我将令牌明确地存储在状态中,这是我想要避免的。
我试图做这样的事情:
function Questionnaire() {
const [token, setToken] = useState(null);
return (
<View>
{(() => {
Keychain.getGenericPassword().then(credentials => {
const token = credentials.password.replace('Bearer ', '');
return
(
<View>
... // do something with the token
</View>
);
});
})()}
</View>
);
}
但这只会返回任何内容(因为这可能是一个承诺)。
我该如何解决此类问题?
编辑
我还尝试获取网页并将其置于状态。问题在于,这只是一个html页面,因此在webview中呈现的页面功能不是很好。
答案 0 :(得分:0)
React不允许您等待,推迟或延迟渲染。您必须先渲染某些东西,然后在诺言解决后再替换它。而且,您应该将副作用置于 useEffect 钩子或 componentDidMount 生命周期方法中。
答案 1 :(得分:0)
我选择仍将令牌存储在状态中,但是将其重置为useEffect挂钩中的匿名清除函数。
function Questionnaire() {
const [token, setToken] = useState(null);
const navigation = useNavigation();
useEffect(() => {
Keychain.getGenericPassword().then(credentials => {
const token = credentials.password.replace('Bearer ', '');
setToken(token);
});
return () => {
setToken(null); // reset the token stored in the questionnaire state (token can still be retrieved from keychain)
};
}, []);
return token ? (
<WebView
source={{
uri: url?token=${token},
}}
...
/>
) : (
<Text>Loading...</Text>
);
}