[SOLVED] React native View’ cannot be used as a JSX component. Its instance type ‘View’ is not a valid JSX element

Question

This Content is from Stack Overflow. Question asked by ramanujans alkhazarim

I´am currently getting the following error on the View component inside App.tsx: ‘View’ cannot be used as a JSX component. Its instance type ‘View’ is not a valid JSX element

I think the issue is related to the library

import React from 'react';

import {View,Text,StyleSheet, Button} from 'react-native'

import {createSwitchNavigator} from 'react-navigation'

const styles = StyleSheet.create({
  txt:{
    fontSize: 48
  },
  view: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center'
  }
})

class screenComponent1 extends React.Component {
  render() {
    return(
      
      <View>
        <Button onPress={() => this.props.navigation.navigate('screenroute2')} title='next page'/>
      </View>
    )
  }
}
class screenComponent2 extends React.Component {
  render() {
    return(
      <View>
        <Button onPress={() => this.props.navigation.navigate('screenroute1')} title='next page'/>
      </View>
    )
  }
}

const AppNavigator = createSwitchNavigator({
  screenroute1: screenComponent1,
  screenroute2: screenComponent2,
})


export default class App extends React.Component {
  render() {
    return <AppNavigator/>
  }
}

Solution

A component needs to return a single root element. You can use fragments to package an array of elements as a single element, by using the fragment as that single root element.

So this does nothing:

function Todos(): JSX.Element {
  return todos.map(todo => (
    <>
      <li>{todo.task}</li>
    </>
  )
}

Because it’s now returning an array of [<><li/></>, <><li/></>, ...]. That fragment needs to be the single root element.

You need to use the fragment like this:

function Todos(): JSX.Element {
  return <>{
    todos.map(todo => <li>{todo.task}</li>)
  }</>
}

You nest all returned JSX in one single fragment.

Using that pattern you may end up with somehting like this:

function Todos(): JSX.Element {
  const todos = useSelector((state: RootState) => state.todos);
  const footer = useSelector((state: RootState) => state.footer);

  if (footer.hideAll) {
    if (footer.showCompleted) {
      return <>{
        todos
          .filter((todo) => !todo.completed)
          .map((todo: any) => (
            <ul>
              <Todo todo={todo} />
            </ul>
          ))
      }</>
    }
    return <>{
      todos.map((todo) => (
        <div>
          <Todo todo={todo} />
        </div>
      ))
    }</>
  }

  return <>{
    todos.map(() => (
      <div></div>
    ))
  }</>
}

// Works without error
<Todos />

Note how each return statement returns just one JSX.Element: the fragment.

Playground

Answered by Alex Wayne


This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 4.0.

people found this article helpful. What about you?