'Converting Class to function with hooks

I'm stuck with converting a Class component to a function / const while using hooks.

I'm getting this Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.

I googled this warning but only saw this warning with Classes, did I convert this Class wrong?

const MyComponent = (props) => {
  const position = new Animated.ValueXY()
  const [index, setIndex] = useState(props.index || 0)

  const rotate = position.x.interpolate({
    inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
    outputRange: ['-30deg', '0deg', '10deg'],
    extrapolate: 'clamp',
  })

  const rotateAndTranslate = {
    transform: [
      {
        rotate: rotate,
      },
      position.getTranslateTransform(),
    ],
  }

  const likeOpacity = position.x.interpolate({
    inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
    outputRange: [0, 0, 1],
    extrapolate: 'clamp',
  })
  const dislikeOpacity = position.x.interpolate({
    inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
    outputRange: [1, 0, 0],
    extrapolate: 'clamp',
  })

  const nextCardOpacity = position.x.interpolate({
    inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
    outputRange: [1, 0, 1],
    extrapolate: 'clamp',
  })
  const nextCardScale = position.x.interpolate({
    inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
    outputRange: [1, 0.8, 1],
    extrapolate: 'clamp',
  })

  useEffect(() => {
    PanResponder.create({
      onStartShouldSetPanResponder: (evt, gestureState) => true,
      onPanResponderMove: (evt, gestureState) => {
        position.setValue({ x: gestureState.dx, y: gestureState.dy })
      },
      onPanResponderRelease: (evt, gestureState) => {
        if (gestureState.dx > 120) {
          Animated.spring(position, {
            toValue: { x: SCREEN_WIDTH + 100, y: gestureState.dy },
            useNativedriver: true,
          }).start(() => {
            setIndex(index + 1, () => {
              position.setValue({ x: 0, y: 0 })
            })
          })
        } else if (gestureState.dx < -120) {
          Animated.spring(position, {
            toValue: { x: -SCREEN_WIDTH - 100, y: gestureState.dy },
            useNativedriver: true,
          }).start(() => {
            setIndex(index + 1, () => {
              position.setValue({ x: 0, y: 0 })
            })
          })
        } else {
          Animated.spring(position, {
            toValue: { x: 0, y: 0 },
            friction: 4,
            useNativedriver: true,
          }).start()
        }
      },
    })
  }, [])

  const Users = () => {
    return imagesData
      .map((item, i) => {
        if (i < index) {
          return null
        } else if (i == index) {
          return (
            <Animated.View
              {...PanResponder.panHandlers}
              key={item.id}
              style={[
                rotateAndTranslate,
                {
                  height: SCREEN_HEIGHT - 120,
                  width: SCREEN_WIDTH,
                  padding: 10,
                  position: 'absolute',
                },
              ]}
            >
              <Animated.View
                style={{
                  opacity: likeOpacity,
                  transform: [{ rotate: '-30deg' }],
                  position: 'absolute',
                  top: 50,
                  left: 40,
                  zIndex: 1000,
                }}
              >
                <Text
                  style={{
                    borderWidth: 1,
                    borderColor: 'green',
                    color: 'green',
                    fontSize: 32,
                    fontWeight: '800',
                    padding: 10,
                  }}
                >
                  LIKE
                </Text>
              </Animated.View>

              <Animated.View
                style={{
                  opacity: dislikeOpacity,
                  transform: [{ rotate: '30deg' }],
                  position: 'absolute',
                  top: 50,
                  right: 40,
                  zIndex: 1000,
                }}
              >
                <Text
                  style={{
                    borderWidth: 1,
                    borderColor: 'red',
                    color: 'red',
                    fontSize: 32,
                    fontWeight: '800',
                    padding: 10,
                  }}
                >
                  NOPE
                </Text>
              </Animated.View>

              <Image
                style={{ height: '86%', width: null, borderRadius: 10 }}
                source={{ uri: `${item.url}` }}
              />
              <View
                style={{
                  backgroundColor: '',
                  color: 'black',
                  fontSize: 20,
                  fontWeight: '800',
                  position: 'absolute',
                  bottom: 95,
                  right: 40,
                  zIndex: 1000,
                  width: '85%',
                  height: '20%',
                  borderRadiusTop: 20,
                }}
              >
                <Text
                  style={{ color: 'white', fontSize: 32, fontWeight: '800' }}
                >
                  Black cat
                </Text>
                <Text
                  style={{ color: 'white', fontSize: 18, fontWeight: '600' }}
                >
                  Black cat family
                </Text>
                <View style={styles.iconen}>
                  <Ionicons style={styles.icon} name="timer" />
                  <Text style={styles.subtitle}>12 -14</Text>
                  <Ionicons style={styles.icon} name="barbell-outline" />
                  <Text style={styles.subtitle}>12 - 14</Text>
                  <Ionicons style={styles.icon} name="earth" />
                  <Text style={styles.subtitle}>Belgium</Text>
                </View>
              </View>
            </Animated.View>
          )
        } else {
          return (
            <Animated.View
              key={item.id}
              style={[
                {
                  opacity: nextCardOpacity,
                  transform: [{ scale: nextCardScale }],
                  height: SCREEN_HEIGHT - 120,
                  width: SCREEN_WIDTH,
                  padding: 10,
                  position: 'absolute',
                },
              ]}
            >
              <Animated.View
                style={{
                  opacity: 0,
                  transform: [{ rotate: '-30deg' }],
                  position: 'absolute',
                  top: 50,
                  left: 40,
                  zIndex: 1000,
                }}
              >
                <Text
                  style={{
                    borderWidth: 1,
                    borderColor: 'green',
                    color: 'green',
                    fontSize: 32,
                    fontWeight: '800',
                    padding: 10,
                  }}
                >
                  LIKE
                </Text>
              </Animated.View>

              <Animated.View
                style={{
                  opacity: 0,
                  transform: [{ rotate: '30deg' }],
                  position: 'absolute',
                  top: 50,
                  right: 40,
                  zIndex: 1000,
                }}
              >
                <Text
                  style={{
                    borderWidth: 1,
                    borderColor: 'red',
                    color: 'red',
                    fontSize: 32,
                    fontWeight: '800',
                    padding: 10,
                  }}
                >
                  NOPE
                </Text>
              </Animated.View>

              <Image
                style={{ height: '86%', width: null, borderRadius: 10 }}
                source={{ uri: `${item.url}` }}
              />
            </Animated.View>
          )
        }
      })
      .reverse()
  }

  return (
    <View>
      <View>{Users}</View>
      <View style={{ height: SCREEN_HEIGHT - 80 }}>
        <ButtonVote />
      </View>
    </View>
  )
}


Solution 1:[1]

Users is a component, you should call it like

<Users />

instead of

{Users}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 fmsthird