Я пытаюсь получить данные из firebase и отобразить их внутри компонента Todo, inputForm использует избыточную форму для обработки проверки. После отправки формы она вызывает создателя действий, который добавляет данные в базу данных firestore, а затем перечисляет элементы задач с помощью создателя действий listTodo, все эти запросы являются асинхронными и используют избыточный преобразователь в качестве промежуточного программного обеспечения, когда у меня есть список элементов задач. на экране, и я пытаюсь удалить последний элемент задачи, он не удаляется при первом нажатии, но мне нужно дважды щелкнуть, чтобы удалить элемент. Я не могу решить эту проблему, кто-нибудь помогите мне с этой проблемой.
App.js
class App extends React.Component {
render() {
return (
<Container fluid>
<h1 className="text-center" style={{marginTop: "5vh"}}>Todo App</h1>
<InputForm/>
<Todo />
</Container>
)
}
}
export default App
InputForm.js
import React from 'react'
import { Button, Col, Container, Form, Row } from 'react-bootstrap'
import { connect } from 'react-redux';
import { Field, reduxForm } from 'redux-form';
import {addTodo } from '../actions'
class InputForm extends React.Component {
renderError = ({error, touched}) => {
if(error && touched){
return <p style={{color: 'red'}}>{error}</p>
}
}
todoInput = ({input, meta}) => {
return (
<Form.Group>
<Form.Control {...input} />
{this.renderError(meta)}
</Form.Group>
);
};
todoDate = ({input, meta}) => {
return (
<Form.Group>
<Form.Control type="date" {...input} />
{this.renderError(meta)}
</Form.Group>
);
};
handleSubmit = (inputValues) => {
this.props.addTodo(inputValues);
inputValues.todo_input = null;
inputValues.todo_date = null;
}
render() {
return (
<Container fluid style={{marginTop: "12vh", marginBottom: "2.5%"}}>
<Form onSubmit={this.props.handleSubmit(this.handleSubmit)}> {/* just need to pass values to addtodo actions */}
<Row lg="auto" style={{marginLeft: "10%"}} >
<Col md={6}>
<Field name="todo_input" component={this.todoInput} />
</Col><Col md="auto" >
<Field name="todo_date" component={this.todoDate} />
</Col><Col xs="auto" >
<Button type="submit" variant="success">Add Todo</Button>
</Col>
</Row>
</Form>
</Container>
)
}
}
const validate = (inputValue) => {
const errors = {};
//error.something, here something must match the value of name of a Field component
if(!inputValue.todo_input){
//only ran if title is empty
errors.todo_input = "Please enter the todo";
}
if(!inputValue.todo_date){
errors.todo_date ="Please enter the deadline"
}
return errors;
}
export default connect(null, {addTodo})(reduxForm({
form: 'todo-input',
validate
})(InputForm));
Todo.js
import React from 'react'
import { Col, ListGroup, Row } from 'react-bootstrap'
import DeleteIcon from '@material-ui/icons/Delete';
import {deleteTodo} from '../actions'
import {listTodo} from '../actions'
import {connect} from 'react-redux'
class Todo extends React.Component {
componentDidMount(){
this.props.listTodo();
}
render(){
if(this.props.list.length === 0){
return (
<ListGroup.Item className="w-50 mx-auto my-2" variant="success" style={{}}>
<Row>
<h5 className="mx-auto text-center">Enter the todo item</h5>
</Row>
<Row>
<p className="mx-auto">Deadline date will be mentioned here</p>
</Row>
</ListGroup.Item>
)
}
if(this.props.list)
//<div>Hello</div>
return this.props.list.map(todo => {
//console.log(todo);
return (
<ListGroup key={todo.id}>
<ListGroup.Item className="w-50 mx-auto my-2" variant="success">
<Row>
<Col xs={1}>
<DeleteIcon onClick={() => this.props.deleteTodo(todo.id)}/>
</Col><Col md={10}>
<h5 className="text-center">{todo.todo.todo}</h5>
</Col>
</Row>
<Row>
<p className="mx-auto">Deadline by {todo.todo.date}</p>
</Row>
</ListGroup.Item>
</ListGroup>
)
})
}
}
const mapStateToProps = (state) => {
console.log(state.todoList);
return {
list: state.todoList
};
}
export default connect(mapStateToProps, {deleteTodo, listTodo})(Todo)
действия/index.js
import database from '../firebase/firebase'
export const addTodo = (inputValue) => async dispatch => {
await database.collection('Todo').add({
todo: inputValue.todo_input,
date: inputValue.todo_date
});
sendTodo(dispatch);
}
export const listTodo = () => async dispatch=> {
//console.log("Hi")
sendTodo(dispatch);
}
export const deleteTodo = id => async dispatch => {
//delete todo
database.collection('Todo').doc(id).delete();
sendTodo(dispatch);
}
const sendTodo = async (dispatch) => {
let data = [];
let todoRef = database.collection('Todo');
let allTodos = await todoRef.orderBy('todo').get();
for(const doc of allTodos.docs){
data.push({
id: doc.id,
todo: doc.data()
})
}
//console.log(data);
dispatch ({
type: 'LIST_TODO',
payload: data
});
}
редуктор.js
import { combineReducers } from "redux";
import {reducer as formReducer} from 'redux-form'
import todoReducer from './TodoReducer'
export default combineReducers({
form: formReducer,
todoList: todoReducer
});
Кроме того, иногда, даже если я не отправил форму, я получаю сообщение об ошибке на своем экране, может ли кто-нибудь помочь мне в этом!