Zainul Abideen
Zainul Abideen

Reputation: 1900

Unable to update state with Array of objects in RN

I have a blank array in the state object. The array will contain some objects with key-value pair.

Here is my code:

import * as React from 'react';
import { Text, ScrollView, View, StyleSheet, TouchableOpacity, TextInput, ListView, Switch, Button } from 'react-native';
import { Constants } from 'expo';


export default class App extends React.Component {

  constructor(props){
    super(props);
    this.ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

    this.state = {
      TodoTextVal: '',
      todos: []
    }

    this.addTodo = this.addTodo.bind(this);
  }

  addTodo() {
    id++;
    let TodoTextVal = this.state.TodoTextVal;
    //let arrVal = {id: id, text: TodoTextVal, checked: false}
    //this.setState(prevState => ({todos : [...prevState.todos, arrVal]}));
    this.setState({
      todos: [
        ...this.state.todos,
        {id: id, text: TodoTextVal, checked: false}
      ], 
    })

  }

  toggle(id) {

  }

  render() {
    return (
      <View style={styles.container}>
        <View style={{flexDirection: "row"}}>
          <TextInput
            onChangeText={(TodoTextVal) => this.setState({TodoTextVal})} 
            ref= {(el) => { this.TodoTextVal = el; }}
            style={[styles.input, {flex: 2} ]} 
            placeholder="Add Todo..."/>
          <TouchableOpacity onPress={this.addTodo} title="+ Add" style={styles.button} >
            <Text>Add</Text>
          </TouchableOpacity>
        </View>

        <ListView 
          dataSource={this.ds.cloneWithRows(this.state.todos)}
          renderRow={(data) => <View><Text>{data}</Text></View>} />

      </View>
    );
  }
}

let id = 0

The problem here is this.setState() is not updating the state. I've tried both the method which you see in addTodo() that commented code too.

But both the methods are throwing an error with this message:

Device: (96:380) Invariant Violation: Objects are not valid as a React child (found: object with keys {id, text, checked}).

Upvotes: 0

Views: 309

Answers (2)

rht
rht

Reputation: 106

First, stop using ListView. It's deprecated and second, update your renderRow method to render individual keys of the object instead of the complete object.

Upvotes: 1

Kabbany
Kabbany

Reputation: 515

I think the problem is in:

renderRow={(data) => <View><Text>{data}</Text></View>}

Data is an object and you are trying to render it. JSX cannot render objects, instead select any key of data object to construct your html.

Upvotes: 1

Related Questions