Hendro Febrian
Hendro Febrian

Reputation: 222

react-native AJAX&API - Render JSON data

I'm really newbie to react. My question is how to iterate component and render json data. Here's my code:

import React from 'react';
import { ScrollView, StyleSheet, Text, View } from 'react-native';
import { Divider } from 'react-native-elements';
import { limitUI04 } from 'uuid-js';


export default class SearchProperty extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      items: []
    }
  }

  componentDidMount() {
    fetch("myapiendpoint", {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
    })
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            items: result.data
          });
        },
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

  render() {
    const { error, isLoaded, items } = this.state;
    {
      items.map(key => {
        return (
          <Text>
            {key.id}
          </Text>
        )
      })
    }
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

My code above return error:

Invariant Violation: Invariant Violation: SearchProperty(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.

Please help

Upvotes: 0

Views: 115

Answers (1)

Bens Steves
Bens Steves

Reputation: 2849

You're missing the return statement after render

render() {
    const { error, isLoaded, items } = this.state;
    return (
     <div>
      {
       items.map(key => {
        return (
          <Text key={key.id}>
            {key.id}
          </Text>
        )
      })
    }
   </div>
  }
 )
}

that's it should be good to go.

Note: remember when you map something the outer most element or your root element in the return statement of the map function must include a unique key. Since I assume your key.id is unique, you can use that as your unique key.

Updated Answer:

import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
class App extends Component {
  state = {
    error: null,
    isLoaded: false,
    items: [
      { id: 1, name: "Apples", price: "$2" },
      { id: 2, name: "Peaches", price: "$5" }
    ]
  };
  componentWillMount() {
    this.setState({ items: [...this.state.items, { id: 3 }] }, () => {
      this.displayItems(this.state.items);
    });
  }
  displayItems = items => {
    console.log(items);
    return items.map(key => {
      return <div key={key.id}>{key.id}</div>;
    });
  };
  render() {
    const { items } = this.state;
    return <div>{this.displayItems(items)}</div>;
  }
}

export default App;

The I changed didMount to WillMount(). The WillMount() will mount (pun not intended) before anything is rendered. Then the component will render the map function. So the state is updated. I sent the items from the WillMount() to a new function displayItems for extra assurance that the state will update. Hope this helps.

Edit: WARNING

I used WillMount() here but I did not include UNSAFE. componentWillMount() will no longer work after version 17. You can use UNSAFE_componentWillMount(). That will work through version 17. Sorry about that (I'm used to just picking that from IntelliSense).

Upvotes: 1

Related Questions