React Native: Не удается прочитать свойство «состояние» неопределенного

#javascript #reactjs #react-native

Вопрос:

Я довольно новичок в… во всем, я возился с некоторым кодом, который получил с GitHub, и менял его, чтобы придать ему свой собственный оборот, но я столкнулся с довольно большим количеством проблем, я знаю, что есть очень похожие вопросы, но я новичок до такой степени, что не могу понять, как они это исправляют, я бы действительно попросил помощи… желательно объяснить для начинающего.

Спасибо, Лачи.

 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 amp;amp; (
        <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_modulesreact-nativeLibrariesLogBoxLogBox.js:148:8 in registerError
at node_modulesreact-nativeLibrariesLogBoxLogBox.js:59:8 in errorImpl
at node_modulesreact-nativeLibrariesLogBoxLogBox.js:33:4 in console.error
at node_modulesexpobuildenvironmentreact-native-logs.fx.js:27:4 in error
at node_modulesreact-nativeLibrariesCoreExceptionsManager.js:104:6 in reportException
at node_modulesreact-nativeLibrariesCoreExceptionsManager.js:171:19 in handleException
at node_modulesreact-nativeLibrariesCoreReactFiberErrorDialog.js:43:2 in showErrorDialog
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:15257:32 in logCapturedError
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:15361:20 in logError
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:16633:16 in callback
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:7106:2 in callCallback
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:7127:20 in commitUpdateQueue
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:15777:25 in commitLifeCycles
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:18744:22 in commitLayoutEffects
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:265:4 in invokeGuardedCallbackImpl
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:476:2 in invokeGuardedCallback
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:18483:29 in commitRootImpl
at node_modulesschedulercjsscheduler.development.js:653:23 in unstable_runWithPriority
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:18317:17 in commitRoot
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:17697:12 in performSyncWorkOnRoot
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:5321:31 in runWithPriority$argument_1
at node_modulesschedulercjsscheduler.development.js:653:23 in unstable_runWithPriority
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:5316:21 in flushSyncCallbackQueueImpl
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:5304:28 in flushSyncCallbackQueue
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:17718:28 in batchedUpdates$1
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:2492:29 in batchedUpdates
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:2638:16 in _receiveRootNodeIDEvent
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:2767:27 in receiveTouches
at node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.js:416:4 in __callFunction
at node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.js:109:6 in __guard$argument_0
at node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.js:364:10 in __guard
at node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.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_modulesreact-nativeLibrariesLogBoxLogBox.js:148:8 in registerError
at node_modulesreact-nativeLibrariesLogBoxLogBox.js:59:8 in errorImpl
at node_modulesreact-nativeLibrariesLogBoxLogBox.js:33:4 in console.error
at node_modulesexpobuildenvironmentreact-native-logs.fx.js:27:4 in error
at node_modulesreact-nativeLibrariesCoreExceptionsManager.js:104:6 in reportException
at node_modulesreact-nativeLibrariesCoreExceptionsManager.js:171:19 in handleException
at node_modulesreact-nativeLibrariesCoreReactFiberErrorDialog.js:43:2 in showErrorDialog
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:15257:32 in logCapturedError
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:15361:20 in logError
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:16597:12 in update.callback
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:7106:2 in callCallback
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:7127:20 in commitUpdateQueue
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:15801:25 in commitLifeCycles
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:18744:22 in commitLayoutEffects
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:265:4 in invokeGuardedCallbackImpl
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:476:2 in invokeGuardedCallback
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:18483:29 in commitRootImpl
at node_modulesschedulercjsscheduler.development.js:653:23 in unstable_runWithPriority
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:18317:17 in commitRoot
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:17697:12 in performSyncWorkOnRoot
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:5321:31 in runWithPriority$argument_1
at node_modulesschedulercjsscheduler.development.js:653:23 in unstable_runWithPriority
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:5316:21 in flushSyncCallbackQueueImpl
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:5304:28 in flushSyncCallbackQueue
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:17718:28 in batchedUpdates$1
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:2492:29 in batchedUpdates
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:2638:16 in _receiveRootNodeIDEvent
at node_modulesreact-nativeLibrariesRendererimplementationsReactNativeRenderer-dev.js:2767:27 in receiveTouches
at node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.js:416:4 in __callFunction
at node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.js:109:6 in __guard$argument_0
at node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.js:364:10 in __guard
at node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.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_modulesreact-nativeLibrariesLogBoxLogBox.js:148:8 in registerError
at node_modulesreact-nativeLibrariesLogBoxLogBox.js:59:8 in errorImpl
at node_modulesreact-nativeLibrariesLogBoxLogBox.js:33:4 in console.error
at node_modulesexpobuildenvironmentreact-native-logs.fx.js:27:4 in error
at node_modulesreact-nativeLibrariesCoreExceptionsManager.js:104:6 in reportException
at node_modulesreact-nativeLibrariesCoreExceptionsManager.js:171:19 in handleException
at node_modulesreact-nativeLibrariesCoresetUpErrorHandling.js:24:6 in handleError
at node_modulesexpo-error-recoverybuildErrorRecovery.fx.js:12:21 in ErrorUtils.setGlobalHandler$argument_0
at node_modulesregenerator-runtimeruntime.js:63:36 in tryCatch
at node_modulesregenerator-runtimeruntime.js:294:29 in invoke
at node_modulesregenerator-runtimeruntime.js:63:36 in tryCatch
at node_modulesregenerator-runtimeruntime.js:155:27 in invoke
at node_modulesregenerator-runtimeruntime.js:165:18 in PromiseImpl.resolve.then$argument_0
at node_modulesreact-nativenode_modulespromisesetimmediatecore.js:37:13 in tryCallOne
at node_modulesreact-nativenode_modulespromisesetimmediatecore.js:123:24 in setImmediate$argument_0   
at node_modulesreact-nativeLibrariesCoreTimersJSTimers.js:130:14 in _callTimer
at node_modulesreact-nativeLibrariesCoreTimersJSTimers.js:181:14 in _callImmediatesPass
at node_modulesreact-nativeLibrariesCoreTimersJSTimers.js:441:30 in callImmediates
at node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.js:387:6 in __callImmediates
at node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.js:135:6 in __guard$argument_0
at node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.js:364:10 in __guard
at node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.js:134:4 in flushedQueue 

Комментарии:

1. я не думаю, что вы можете использовать конструктор и this.state внутри функционального компонента

2. Покажите нам полный журнал ошибок, пожалуйста

3. @Нико, как бы я это исправил?..

4. @yesIamFaded добавил.

5. @StanLachie проверь мой ответ

Ответ №1:

Вы смешиваете компоненты класса и функциональные компоненты. Вы не можете использовать this.state api или другие компоненты класса внутри функциональных компонентов, вместо этого вы должны использовать крючки.
Я предлагаю прочитать документы react для лучшего понимания.
Этот код, использующий крючки, должен работать :
Изменить : песочница

 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 amp;amp; (
        <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;
 

Комментарии:

1. Эй, Нико, исправлены все ошибки, но возникли некоторые собственные проблемы, а именно возможность редактирования текста внутри текстового ввода. какие-нибудь исправления?

2. @StanLachie смотрите мой комментарий value="StanLachie" // this should be text , так что, должно быть value={text} , я обновил sandobx

Ответ №2:

Спасибо @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 amp;amp; (
        <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
  }
});