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
}