0

我目前正在使用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 中渲染的页面不是很实用。

4

2 回答 2

0

React 不允许您等待、推迟或延迟渲染。你必须渲染一些东西,然后你可以稍后在你的承诺解决时替换它。您应该将副作用放置在useEffect挂钩或componentDidMount生命周期方法中。

于 2020-03-22T15:58:14.163 回答
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>
  );
}
于 2020-03-24T11:50:03.677 回答