为什么我的最后一个待办事项在 react redux 中第一次点击时没有被删除

问题描述

我正在尝试从 firebase 获取数据并尝试将其显示在 Todo 组件中,inputForm 使用 redux-form 来处理验证。提交表单后,它会调用将数据添加到 Firestore 数据库的操作创建器,然后使用“listTodo”操作创建器列出待办事项,所有这些请求都是异步的,并使用 redux-thunk 作为中间件,当我有列表时屏幕上的待办事项,我尝试删除最后一个待办事项,第一次点击时它不会被删除,但我必须单击两次才能删除该项目。我无法解决这个问题,任何人都可以帮我解决这个问题。

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)

actions/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
     });
}

reducer.js

import { combineReducers } from "redux";
import {reducer as formReducer} from 'redux-form'
import todoReducer from './TodoReducer'

export default combineReducers({
    form: formReducer,todoList: todoReducer
});

另外,有时即使没有提交表单,我的屏幕上也会出现错误,有人可以帮我解决这个问题!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)