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
相关产品推荐
相关产品推荐

