You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中Plaid API认证流程无法启动问题求助

问题

在React Native应用中集成Plaid,参考Quickstart项目开发,已在沙箱环境成功生成link token,但点击PlaidLink组件时无任何反应,且抛出如下错误:

Possible Unhandled Promise Rejection (id: 0):
TypeError: Cannot read property 'create' of null
TypeError: Cannot read property 'create' of null
    at ?anon_0_ (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:130387:52)
    at next (native)
    at anonymous (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:130348:73)
    at tryCallTwo (/private/var/folders/yw/6bx918xn4671rggfcdxz7fph0000gn/T/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:61:9)
    at doResolve (/private/var/folders/yw/6bx918xn4671rggfcdxz7fph0000gn/T/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:216:25)
    at Promise (/private/var/folders/yw/6bx918xn4671rggfcdxz7fph0000gn/T/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:82:14)
    at anonymous (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:130330:36)
    at openLink (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:130369:21)
    at onPress (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:130416:15)
    at _performTransitionSideEffects (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:81778:22)
    at _receiveSignal (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:81728:45)
    at onResponderRelease (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:81584:34)
    at apply (native)
    at invokeGuardedCallbackProd (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:82294:21)
    at apply (native)
    at invokeGuardedCallback (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:82470:42)
    at apply (native)
    at invokeGuardedCallbackAndCatchFirstError (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:82484:36)
    at executeDispatch (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:82561:48)
    at executeDispatchesInOrder (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:82583:26)
    at executeDispatchesAndRelease (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:84354:35)
    at executeDispatchesAndReleaseTopLevel (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:84361:43)
    at forEach (native)
    at forEachAccumulated (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:83175:22)
    at runEventsInBatch (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:84374:27)
    at runExtractedPluginEventsInBatch (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:84484:25)
    at anonymous (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:84455:42)
    at batchedUpdates$1 (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:97896:20)
    at batchedUpdates (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:84330:36)
    at _receiveRootNodeIDEvent (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:84454:23)
    at receiveTouches (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:84543:34)
    at apply (native)
    at __callFunction (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:3679:36)
    at anonymous (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:3399:31)
    at __guard (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:3616:15)
    at callFunctionReturnFlushedQueue (http://192.168.100.11:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true:3398:21)
 LOG  Link token is  link-sandbox-c29d2a47-2da9-4a7b-a56d-9d02edc46c2d

相关页面代码:

import { StatusBar } from 'expo-status-bar';
import { useState, useCallback, useEffect } from 'react';

import { StyleSheet, Text, View, Dimensions } from 'react-native';
import PlaidLink, { LinkSuccess, LinkExit, usePlaidEmitter } from 'react-native-plaid-link-sdk';


let height = Dimensions.get('window').height;
let width = Dimensions.get('window').width;

export default function App() {

  const [linkToken, setLinkToken] = useState(null);
  const address = '7019-116-90-112-9.ngrok-free.app'//Platform.OS === 'ios' ? 'localhost' : '10.0.2.2';



  const createLinkToken = useCallback(async () => {
    await fetch(`https://${address}/api/plaid/create_link_token`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      // "Authorization": "Bearer " + u.token,
    },
    body: JSON.stringify({ address: address })
    })
    .then((response) => response.json())
    .then((data) => {
      console.log(data.data.link_token)
      setLinkToken(data.data.link_token);
    })
    .catch((err) => {
      console.log(err);
    });
  }, [setLinkToken])

  useEffect(() => {
    if (linkToken == null) {
      createLinkToken();
    }
    console.log("Link token is ", linkToken)
  }, [linkToken]);

  
  return (
    <View style={{flex: 1, height: height, width: width, justifyContent: 'center', alignItems: 'center'}}>
      
      <View style={styles.bottom}>
        <PlaidLink
          tokenConfig={{
            token: linkToken,
            logLevel: 'DEBUG'
          }}
          onSuccess={(success) => {
            console.log(success);
          }}
          onExit={(exit) => {
            // console.log(exit);
          }}
        >
          <Text>Add Account</Text>
        </PlaidLink>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'red',
    alignItems: 'center',
    justifyContent: 'center',
    height: height,
    width: width
  },
});

可能的原因及解决办法

  • Plaid原生模块未正确加载:TypeError: Cannot read property 'create' of null核心原因是原生模块未初始化。如果是Expo项目,需确认是否使用了Expo官方支持的expo-plaid-link库,而非普通的react-native-plaid-link-sdk,并在app.json中配置好Plaid的client ID等参数;如果是裸React Native项目,需重新执行pod install(iOS)或检查Android原生模块的链接状态。
  • Link Token加载时机问题:虽然日志显示token已生成,但组件渲染时可能token仍未就绪。给PlaidLink组件添加条件渲染,确保token存在时才渲染:
    {linkToken && (
      <PlaidLink
        tokenConfig={{
          token: linkToken,
          logLevel: 'DEBUG'
        }}
        onSuccess={(success) => {
          console.log(success);
        }}
        onExit={(exit) => {
          // console.log(exit);
        }}
      >
        <Text>Add Account</Text>
      </PlaidLink>
    )}
    
  • 版本兼容性问题:检查react-native-plaid-link-sdk(或expo-plaid-link)与当前React Native/Expo SDK的版本是否匹配,参考Plaid官方文档的版本适配表,升级或降级到兼容版本。
  • 沙箱环境配置问题:确认后端生成link token时使用的沙箱client ID、secret是否正确,且请求的Plaid环境为sandbox,避免因配置错误导致token无效。

内容的提问来源于stack exchange,提问作者Tech Labs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 12:05:56