【问题标题】:React Native conditional rendering based on token without storage inside component state基于令牌的 React Native 条件渲染,不存储在组件状态中
【发布时间】:2020-03-22 14:20:52
【问题描述】:

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

【问题讨论】:

    标签: reactjs react-native react-native-keychain


    【解决方案1】:

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

    【讨论】:

    • 我明白你在说什么,但我仍然不知道在这种情况下我将如何替换内容。我不希望将令牌存储在状态中,并且将整个组件存储在状态中是不好的做法。
    【解决方案2】:

    我选择仍然将令牌存储在状态中,但在 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>
      );
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-11
      • 2021-10-22
      • 2018-12-21
      • 2017-02-03
      • 1970-01-01
      • 2021-01-11
      • 1970-01-01
      • 2020-01-25
      • 1970-01-01
      相关资源
      最近更新 更多