Home > other >  React Native TodoList
React Native TodoList

Time:11-07

I'm working on a code that will give a TodoList in React-Native, my code doesn't create an error but when I want to change a label, the code duplicates my state. I can't find where is my mistake, can someone help me please?

Apps.js `

import React, {Component, useState} from 'react';
import {View,Text,Button, StyleSheet} from 'react-native';
import TodoList from './TodoList';

class Apps extends Component {
    state={
        todos:[
            {id:1,label:'Buy some milk'},
            {id:2,label:'Learn some React'}
        ]
    }

    newTodo = ()=>{
      this.setState({count:this.state.count 1})
      this.setState({todos:[...this.state.todos,...[{id:this.state.count 1,label:'New Task'}]]})
    }

    updateTodoLabel=(todoId,label)=>{
        const{todos}=this.state
        const todoIndex=todos.findIndex(t=>t.id===todoId)
        const todosBefore=todos.slice(0,todoIndex)
        const todosAfter=todos.slice(todoIndex 1)
        const newtodo={...todos[todoIndex],label}
        this.setState({
            todos:[...todosBefore,newtodo,...todosAfter]
        })
    }
    render(){
        const {todos} = this.state
        return(
            <View style={styles.container}>
                <TodoList todos={todos} updateTodoLabel={this.updateTodoLabel}/>
                <Button title="Add" onPress={this.newTodo}/>
            </View>
        )
    }
}

// ...

const styles=StyleSheet.create({
    container:{
        flex:1,
        marginTop:25
    }
})

export default Apps

`

Todo.js `

//src/components/Todo.js
import { Component, Fragment } from 'react';
import {
  View,
  Text,
  StyleSheet,
  Button,
  TextInput,
  TouchableOpacity,
} from 'react-native';

class Todo extends Component {
  state = {
    editMode: false,
    label: this.props.todo.label,
  };

  renderEditMode = () => {
    const { label } = this.state;
    return (
      <Fragment>
        <TextInput
          style={[styles.editInput, styles.todoLabel]}
          value={label}
          onChangeText={this.onChange}
          autoFocus
        />
        <Button title="Save" onPress={this.onSavePress} />
        <Button title="Cancel" onPress={this.onCancelPress} />
      </Fragment>
    );
  };

  onPressButton = () => {
    const { updateTodoLabel } = this.props;
    const { label } = this.state;
    updateTodoLabel(label   '✅');
    this.setState({
      editMode: false,
    });
  };

  render() {
    const { editMode } = this.state;
    return (
      <View style={styles.todo}>
        {editMode ? this.renderEditMode() : this.renderViewMode()}
      </View>
    );
  }

  renderViewMode = () => {
    const { todo } = this.props;
    return (
      <Fragment>
        <TouchableOpacity onPress={this.onPressButton}>
          <Text style={styles.todoLabel}>{todo.label}</Text>
        </TouchableOpacity>
        <Button title="Edit" onPress={this.onEditPress} />
      </Fragment>
    );
  };

  onEditPress = () => {
    this.setState({
      editMode: true,
    });
  };

  onChange = (label) => {
    this.setState({ label });
  };

  onSavePress = () => {
    const { updateTodoLabel } = this.props;
    const { label } = this.state;
    updateTodoLabel(label);
    this.setState({
      editMode: false,
    });
  };

  onCancelPress = () => {
    this.setState({
      editMode: false,
      label: this.props.todo.label,
    });
  };
}

const styles = StyleSheet.create({
  todo: {
    padding: 10,
    borderTopWidth: 1,
    borderStyle: 'solid',
    borderColor: 'lightgray',
  },
  todoLabel: {
    fontSize: 18,
    padding: 10,
    flex: 1,
  },
});

export default Todo;

`

TodoList.js `

//src/components/TodoList.js
import React from 'react';
import {View, StyleSheet,Button} from 'react-native';
import Todo from './Todo';

const TodoList=({todos, updateTodoLabel})=>(
    <View style={styles.todoList}>
        {todos.map(todo =>(
            <Todo 
            todo={todo} 
            updateTodoLabel={label=>updateTodoLabel(todo.id,label)}
            key={todo.id}/>
        ))}
    </View>
)

const styles = StyleSheet.create({
    todoList:{
        flex:1,
        alignItems:'stretch'
    }
})

export default TodoList

`

I trying to give a precise way of the label or to just change the label and to change the old state by the new state but I'm a beginner and I only found errors in this ways.

CodePudding user response:

I found my error, that's was only a mistake on the todos of my state in the Apps.js, I need to get a count:2 after the todos.

state={
    todos:[
        {id:1,label:'Buy some milk'},
        {id:2,label:'Learn some React'}
    ],count:2
}
  • Related