PhilosophOtter
PhilosophOtter

Reputation: 303

React Native can't find variable function that is already declared

I have a small app with FlatList buttons that launch a function outside of the render in a Functional Component. Race.js and Class.js both function JUST FINE. Background.js was not sending the value from the button up to the parent (App.js) as its sibling components were, which is strange... I have copied the EXACT SAME functions and passed the same props for/to all three components, but just changed the names so they point to the relevant components (race, class, background - its a d&d app :P).

Can anyone see something that could be wrong with why one component sees the function and the next doesn't?

The problem is Race.js/Class.js work and 'selectRace' is found and called properly:

import React, { useState } from "react";
import { SafeAreaView, StyleSheet, Text, View } from "react-native";
import { FlatList, TouchableOpacity } from "react-native-gesture-handler";
import { Races } from "../components/races";

const Race = (props) => {
  const razas = props.raceNames;

  selectRace = (race) => {
    console.log("race button pushed: ", race);

    const index = (element) => element.name === race;
    let raceIndex = Races.findIndex(index);
    props.setRace(raceIndex);
  };

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.main}>
        <Text style={styles.titulo}>Elige una Raza:</Text>

        <FlatList
          numColumns={2}
          data={razas}
          renderItem={({ item }) => (
            <View style={styles.gridWrapper} key={item.id}>
              <TouchableOpacity
                style={styles.button}
                onPress={() => {
                  selectRace(`${item.name}`);
                  props.navigation.navigate("Class");
                }}>
                <Text style={styles.text}>{item.name}</Text>
              </TouchableOpacity>
            </View>
          )}
        />
      </View>
    </SafeAreaView>
  );
};

export default Race;

but in Background.js, the SAME EXACT SYNTAX fails and upon rendering the navigation route, it throws an error saying it cannot find the variable "selectBackground" even though it's OBVIOUSLY declared right in the function, the same as the previous two components:

import React, { useState } from "react";
import { SafeAreaView, StyleSheet, Text, View } from "react-native";
import { FlatList, TouchableOpacity } from "react-native-gesture-handler";
import { Backgrounds } from "../components/backgrounds";

const Background = (props) => {
  const backgroundNames = props.backgroundNames;

  selectBackground = (b) => {
    console.log("Background button pushed: ", b);

    const index = (element) => element.name === b;
    let backgroundIndex = Backgrounds.findIndex(index);
    props.setBackground(backgroundIndex);
  };


  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.main}>
        <Text style={styles.titulo}>Elige un Trasfondo:</Text>

        <FlatList
          numColumns={2}
          data={backgroundNames}
          renderItem={({ item }) => (
            <View style={styles.gridWrapper} key={item.id}>
              <TouchableOpacity
                style={styles.button}
                onPress={() => {
                  selectBackground(`${item.name}`);
                  // props.navigation.navigate("Imagen");
                }}>
                <Text style={styles.text}>{item.name}</Text>
              </TouchableOpacity>
            </View>
          )}
        />
      </View>
    </SafeAreaView>
  );
};

export default Background;

What's more frustrating is that before, it was finding it just fine but it simply wasn't hoisting data up to the parent in "props.setBackground(index)" and now it cannot find this "variable" at all...The only thing I change was the name of the prop being passed in so that it wasn't the same as the function itself in the child, just in case having the function called 'selectBackground' and 'props.selectBackground' could possibly cause some kind of issue (I don't leave anything to chance with computers anymore...).

I have also tried lifting it outside the actual component rendering area { const Background = (props) ... } and put the function under the imports as "const selectBackground..." and now my button can find it, and it launched the console.log inside, but then failed when it hit the final line in the function of "props.setBackground()" because obviously it's outside the component receiving the props, and I cannot receive/set props outside there. Why is it doing this?!

Upvotes: 1

Views: 1513

Answers (1)

Farhan Asif
Farhan Asif

Reputation: 158

To make it work you first need to declare your selectBackground function with "const" like:

const selectBackground = (b) =>

and your code will look like:

const Background = (props) => {
  const backgroundNames = props.backgroundNames;

  const selectBackground = (b) => {
    console.log("Background button pushed: ", b);

    const index = (element) => element.name === b;
    let backgroundIndex = Backgrounds.findIndex(index);
    props.setBackground(backgroundIndex);
  };

Second, you can call your function in the way I mentioned the code below:

const callFunction = (value) => {
    console.log(value)
}

<SafeAreaView setBackground={callFunction} />

You need to pass a function to a component without parentheses and then inside a component, you will call it with parentheses.

Upvotes: 1

Related Questions