React Native:无法读取未定义的属性“state”
2021-09-02
2180
我对一切都还不太熟悉,我一直在摆弄从 GitHub 获得的一些代码,并对其进行修改以加入自己的见解,但我遇到了不少问题,我知道有很多类似的问题,但我对它们很陌生,无法理解他们解决问题的方式,我真的需要一些帮助...最好能为初学者解释一下。
谢谢,Lachie。
import React from "react";
import { StyleSheet, Button, Text, TextInput, View } from "react-native";
export default function getSummonerInfo() {
const constructor = (props) => {
this.state = {
url:
"https://oc1.api.riotgames.com/lol/summoner/v4/summoners/by-name/",
apikey: props.apikey,
text: "",
name: null,
summonerLevel: null,
};
};
function handlePress() {
let url =
this.state.url + this.state.text + "?api_key=" + this.state.apikey;
fetch(url)
.then((response) => response.json())
.then((responseJson) => {
this.state.name = responseJson.name;
this.state.summonerLevel = responseJson.summonerLevel;
this.setState({
name: this.state.name,
summonerLevel: this.state.summonerLevel,
});
return responseJson;
})
.catch((error) => {
console.error(error);
this.setState({
name: "Player Not Found!",
summonerLevel: "N/A",
});
});
};
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Summoner name"
value='StanLachie'
onChangeText={(text) => this.setState({ text })}
/>
<Button
color="#841584"
onPress={() => handlePress()}
title={`Search Stats For ""`}
/>
{this.state.name != null && (
<View>
<Text>Summoner Name : {this.state.name}</Text>
<Text>Summoner Level : {this.state.summonerLevel}</Text>
</View>
)}
</View>
);
}
const styles = StyleSheet.create({
input: {
padding: 10,
borderColor: "grey",
borderWidth: 1,
},
container: {
margin: 10,
},
label: {
fontWeight: "bold",
margin: 10,
},
});
完整错误:
TypeError: undefined is not an object (evaluating 'this.state.name')
This error is located at:
in getSummonerInfo (at summonerLookUp.js:9)
in RCTView (at View.js:34)
in View (at summonerLookUp.js:7)
in summonerLookUp (created by SceneView)
in SceneView (created by CardContainer)
in RCTView (at View.js:34)
in View (created by CardContainer)
in RCTView (at View.js:34)
in View (created by CardContainer)
in RCTView (at View.js:34)
in View (created by ForwardRef(CardSheet))
in ForwardRef(CardSheet) (created by Card)
in RCTView (at View.js:34)
in View (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (created by PanGestureHandler)
in PanGestureHandler (created by PanGestureHandler)
in PanGestureHandler (created by Card)
in RCTView (at View.js:34)
in View (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (created by Card)
in RCTView (at View.js:34)
in View (created by Card)
in Card (created by CardContainer)
in CardContainer (created by CardStack)
in RNSScreen (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (at src/index.native.tsx:147)
in Screen (created by MaybeScreen)
in MaybeScreen (created by CardStack)
in RNSScreenContainer (at src/index.native.tsx:186)
in ScreenContainer (created by MaybeScreenContainer)
in MaybeScreenContainer (created by CardStack)
in CardStack (created by Context.Consumer)
in KeyboardManager (created by Context.Consumer)
in RNCSafeAreaProvider (at SafeAreaContext.tsx:76)
in SafeAreaProvider (created by Context.Consumer)
in SafeAreaProviderCompat (created by StackView)
in GestureHandlerRootView (at GestureHandlerRootView.android.tsx:26)
in GestureHandlerRootView (created by StackView)
in StackView (created by StackView)
in StackView
in Unknown (created by Navigator)
in Navigator (created by NavigationContainer)
in NavigationContainer (at App.js:9)
in RCTView (at View.js:34)
in View (at App.js:8)
in main (created by ExpoRoot)
in ExpoRoot (at renderApplication.js:45)
in RCTView (at View.js:34)
in View (at AppContainer.js:106)
in RCTView (at View.js:34)
in View (at AppContainer.js:132)
in AppContainer (at renderApplication.js:39)
at node_modules\react-native\Libraries\LogBox\LogBox.js:148:8 in registerError
at node_modules\react-native\Libraries\LogBox\LogBox.js:59:8 in errorImpl
at node_modules\react-native\Libraries\LogBox\LogBox.js:33:4 in console.error
at node_modules\expo\build\environment\react-native-logs.fx.js:27:4 in error
at node_modules\react-native\Libraries\Core\ExceptionsManager.js:104:6 in reportException
at node_modules\react-native\Libraries\Core\ExceptionsManager.js:171:19 in handleException
at node_modules\react-native\Libraries\Core\ReactFiberErrorDialog.js:43:2 in showErrorDialog
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:15257:32 in logCapturedError
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:15361:20 in logError
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:16633:16 in callback
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:7106:2 in callCallback
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:7127:20 in commitUpdateQueue
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:15777:25 in commitLifeCycles
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:18744:22 in commitLayoutEffects
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:265:4 in invokeGuardedCallbackImpl
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:476:2 in invokeGuardedCallback
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:18483:29 in commitRootImpl
at node_modules\scheduler\cjs\scheduler.development.js:653:23 in unstable_runWithPriority
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:18317:17 in commitRoot
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:17697:12 in performSyncWorkOnRoot
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:5321:31 in runWithPriority$argument_1
at node_modules\scheduler\cjs\scheduler.development.js:653:23 in unstable_runWithPriority
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:5316:21 in flushSyncCallbackQueueImpl
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:5304:28 in flushSyncCallbackQueue
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:17718:28 in batchedUpdates$1
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2492:29 in batchedUpdates
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2638:16 in _receiveRootNodeIDEvent
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2767:27 in receiveTouches
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:416:4 in __callFunction
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:109:6 in __guard$argument_0
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:364:10 in __guard
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:108:4 in callFunctionReturnFlushedQueue
TypeError: undefined is not an object (evaluating 'this.state.name')
This error is located at:
in NavigationContainer (at App.js:9)
in RCTView (at View.js:34)
in View (at App.js:8)
in main (created by ExpoRoot)
in ExpoRoot (at renderApplication.js:45)
in RCTView (at View.js:34)
in View (at AppContainer.js:106)
in RCTView (at View.js:34)
in View (at AppContainer.js:132)
in AppContainer (at renderApplication.js:39)
at node_modules\react-native\Libraries\LogBox\LogBox.js:148:8 in registerError
at node_modules\react-native\Libraries\LogBox\LogBox.js:59:8 in errorImpl
at node_modules\react-native\Libraries\LogBox\LogBox.js:33:4 in console.error
at node_modules\expo\build\environment\react-native-logs.fx.js:27:4 in error
at node_modules\react-native\Libraries\Core\ExceptionsManager.js:104:6 in reportException
at node_modules\react-native\Libraries\Core\ExceptionsManager.js:171:19 in handleException
at node_modules\react-native\Libraries\Core\ReactFiberErrorDialog.js:43:2 in showErrorDialog
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:15257:32 in logCapturedError
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:15361:20 in logError
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:16597:12 in update.callback
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:7106:2 in callCallback
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:7127:20 in commitUpdateQueue
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:15801:25 in commitLifeCycles
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:18744:22 in commitLayoutEffects
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:265:4 in invokeGuardedCallbackImpl
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:476:2 in invokeGuardedCallback
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:18483:29 in commitRootImpl
at node_modules\scheduler\cjs\scheduler.development.js:653:23 in unstable_runWithPriority
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:18317:17 in commitRoot
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:17697:12 in performSyncWorkOnRoot
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:5321:31 in runWithPriority$argument_1
at node_modules\scheduler\cjs\scheduler.development.js:653:23 in unstable_runWithPriority
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:5316:21 in flushSyncCallbackQueueImpl
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:5304:28 in flushSyncCallbackQueue
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:17718:28 in batchedUpdates$1
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2492:29 in batchedUpdates
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2638:16 in _receiveRootNodeIDEvent
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2767:27 in receiveTouches
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:416:4 in __callFunction
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:109:6 in __guard$argument_0
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:364:10 in __guard
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:108:4 in callFunctionReturnFlushedQueue
TypeError: undefined is not an object (evaluating 'this.state.name')
This error is located at:
in NavigationContainer (at App.js:9)
in RCTView (at View.js:34)
in View (at App.js:8)
in main (created by ExpoRoot)
in ExpoRoot (at renderApplication.js:45)
in RCTView (at View.js:34)
in View (at AppContainer.js:106)
in RCTView (at View.js:34)
in View (at AppContainer.js:132)
in AppContainer (at renderApplication.js:39)
at node_modules\react-native\Libraries\LogBox\LogBox.js:148:8 in registerError
at node_modules\react-native\Libraries\LogBox\LogBox.js:59:8 in errorImpl
at node_modules\react-native\Libraries\LogBox\LogBox.js:33:4 in console.error
at node_modules\expo\build\environment\react-native-logs.fx.js:27:4 in error
at node_modules\react-native\Libraries\Core\ExceptionsManager.js:104:6 in reportException
at node_modules\react-native\Libraries\Core\ExceptionsManager.js:171:19 in handleException
at node_modules\react-native\Libraries\Core\setUpErrorHandling.js:24:6 in handleError
at node_modules\expo-error-recovery\build\ErrorRecovery.fx.js:12:21 in ErrorUtils.setGlobalHandler$argument_0
at node_modules\regenerator-runtime\runtime.js:63:36 in tryCatch
at node_modules\regenerator-runtime\runtime.js:294:29 in invoke
at node_modules\regenerator-runtime\runtime.js:63:36 in tryCatch
at node_modules\regenerator-runtime\runtime.js:155:27 in invoke
at node_modules\regenerator-runtime\runtime.js:165:18 in PromiseImpl.resolve.then$argument_0
at node_modules\react-native\node_modules\promise\setimmediate\core.js:37:13 in tryCallOne
at node_modules\react-native\node_modules\promise\setimmediate\core.js:123:24 in setImmediate$argument_0
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:130:14 in _callTimer
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:181:14 in _callImmediatesPass
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:441:30 in callImmediates
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:387:6 in __callImmediates
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:135:6 in __guard$argument_0
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:364:10 in __guard
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:134:4 in flushedQueue
2个回答
您正在混合类组件和功能组件。
您不能在功能组件中使用
this.state
或其他类组件 api,而必须使用钩子。
我建议阅读 react
docs
以更好地理解。
此代码使用钩子应该可以工作:
编辑
:
sandbox
import React, { useState } from "react";
import { StyleSheet, Button, Text, TextInput, View } from "react-native";
const GetSummonerInfo = ({ key }) => {
const [url, setUrl] = useState(
"https://oc1.api.riotgames.com/lol/summoner/v4/summoners/by-name/"
);
const [name, setName] = useState(null);
const [apikey, setApikey] = useState(key);
const [text, setText] = useState("StanLachie");
const [summonerLevel, setSummonerLevel] = useState(null);
function handlePress() {
let Url = url + text + "?api_key=" + apikey;
fetch(Url)
.then((response) => response.json())
.then((responseJson) => {
setName(responseJson.name);
setSummonerLevel(responseJson.summonerLevel);
return responseJson;
})
.catch((error) => {
console.error(error);
setName("Player Not Found!");
setSummonerLevel("N/A");
});
}
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Summoner name"
value={text} // this should be text
onChangeText={(text) => setText(text)}
/>
<Button
color="#841584"
onPress={() => handlePress()}
title={`Search Stats For "${text}"`}
/>
{name != null && (
<View>
<Text>Summoner Name : {name}</Text>
<Text>Summoner Level : {summonerLevel}</Text>
</View>
)}
</View>
);
};
const styles = StyleSheet.create({
input: {
padding: 10,
borderColor: "grey",
borderWidth: 1
},
container: {
margin: 10
},
label: {
fontWeight: "bold",
margin: 10
}
});
export default GetSummonerInfo;
Nico
2021-09-02
感谢@Nico 提供的大部分解决方案,他的代码仍然存在一些问题,我在下面进行了编辑和修复:
import React, { useState } from "react";
import { StyleSheet, Button, Text, TextInput, View } from "react-native";
export default function getSummonerInfo(props) {
const [url, setUrl] = useState(
"https://oc1.api.riotgames.com/lol/summoner/v4/summoners/by-name/"
);
const [name, setName] = useState(null);
const [apikey, setApikey] = useState(props.api);
const [tempPlayer, setTempPlayer] = useState("");
const [summonerLevel, setSummonerLevel] = useState(null);
function handlePress() {
let Url = url + tempPlayer + "?api_key=" + apikey;
fetch(Url)
.then((response) => response.json())
.then((responseJson) => {
setName(responseJson.name)
setSummonerLevel(responseJson.summonerLevel)
return responseJson;
})
.catch((error) => {
console.error(error);
setName("Player Not Found!")
setSummonerLevel( "N/A")
});
}
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Summoner name"
value={tempPlayer}
onChangeText={(text) => setTempPlayer( text )}
/>
<Button
color="#841584"
onPress={() => handlePress()}
title={`Search Stats For "${tempPlayer}"`}
/>
{name != null && (
<View>
<Text>Summoner Name : {name}</Text>
<Text>Summoner Level : {summonerLevel}</Text>
</View>
)}
</View>
);
}
const styles = StyleSheet.create({
input: {
padding: 10,
borderColor: "grey",
borderWidth: 1
},
container: {
margin: 10
},
label: {
fontWeight: "bold",
margin: 10
}
});
StanLachie
2021-09-02