无法在初始渲染中显示待办事项列表

Posted

技术标签:

【中文标题】无法在初始渲染中显示待办事项列表【英文标题】:Unable to show todo List in Initial render in react 【发布时间】:2021-08-07 08:32:06 【问题描述】:

我正在尝试使用 react、redux、redux-form 和 firestore 数据库构建 todoList,我还可以使用操作或操作创建器将待办事项插入数据库中,我可以获取数据库中的数据存储但是当用户第一次访问网站时,我无法在网站上显示数据,当用户添加待办事项并提交表单时,第一个待办事项显示给我空白!有人可以帮我看看我的代码有什么问题吗?

App.js

import React from 'react'
import  Container from 'react-bootstrap'
import  connect  from 'react-redux'
import InputForm from './InputForm'
import Todo from './Todo'
import listTodo from '../actions' 




class App extends React.Component 

    constructor(props)
        super(props);

        this.renderList = this.renderList.bind(this);
    

    componentDidMount()
        this.props.listTodo();
        console.log(this.props.list);
    

    renderList()
        return this.props.list.map((todo,id) => 
            return (
                <Todo todo=todo key=id/>
            )
        )
    

    render() 
        console.log("rendered");
        if(!this.props.list)
            return <div>Loading...</div>
        
        return (
            <Container fluid>
                <h1 className="text-center" style=marginTop: "5vh">Todo App</h1>
                <InputForm />
                this.renderList()
            </Container>
        )
    


const mapStateToProps = (state) => 
    console.log(state.todoList);
    return  
        list: state.todoList
    

export default connect(mapStateToProps, listTodo)(App)

Todo.js

import React from 'react'
import  Card  from 'react-bootstrap'


class Todo extends React.Component 
    
    render()
        console.log(this.props.todo);
        return (
            <Card className="text-center">
                <Card.Body>
                    <Card.Text>this.props.todo.todo</Card.Text>
                </Card.Body>
                <Card.Footer className="text-muted">DeadLine by this.props.todo.date</Card.Footer>
            </Card>
        )
    


export default Todo

动作(index.js)

import database from '../firebase/firebase'

export const addTodo = (inputValue) => 
    database.collection('Todo').add(
        todo: inputValue.todo_input,
        date: inputValue.todo_date
    );
    return 
        type: "ADD_TODO",
        payload: inputValue

    ;


export const listTodo = () => 
    const data = [];
    database.collection('Todo').onSnapshot(snapshot => snapshot.docs.map(doc => data.push(doc.data())));
    return 
        type: 'LIST_TODO',
        payload: data
    


export const deleteTodo = id => 
    //delete todo
    return type: 'DELETE_TODO'

TodoReducer.js

export default (state = [], action) => 
    switch (action.type) 
        case 'ADD_TODO':
            return [...state, action.payload];
        case 'LIST_TODO':
            return action.payload;
        case 'DELETE_TODO':
            return state.filter(item => item.id !== action.payload);
        default:
            return state;
    

reducers.js

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

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

【问题讨论】:

我想第一步是检查this.props.listTodo 是否正在获取(或以其他方式加载)您的待办事项列表。您能否更新您的问题以包括您的操作创建者、reducers 和任何其他影响 todos 的获取/加载/渲染的代码(即所有相关代码)? 同意,没有提到如何获取待办事项列表。您应该首先显示一个占位符/骨架,然后在从服务器获取数据时呈现待办事项列表。 您是否正在运行任何异步操作中间件,例如 Redux-Thunks 之类的东西?数据将被异步获取/加载,您的 redux 存储需要能够处理异步操作。 您好,感谢您的帮助,我对异步等待语法感到困惑,但后来我解决了这个问题 @ChiragLalwani 你是说问题是异步语法并且现在已经解决了吗?或者您解决了异步语法中的特定错误但主要问题仍然存在? 【参考方案1】:

在您的 listTodo 操作创建器中,您创建一个对象 data 并将其作为您的 LIST_TODO 操作的一部分返回。然后这个data 对象被持久化到您的存储中,然后由您的onSnapshot 回调操作,以事后将项目添加到该数据中。 React-Redux 无法检测到这些更改,因此您的组件不会自行更新内容。

export const listTodo = () => 
    const data = [];
    // do never do something like this!
    database.collection('Todo').onSnapshot(snapshot => snapshot.docs.map(doc => data.push(doc.data())));
    return 
        type: 'LIST_TODO',
        payload: data
    

这打破了第二个Redux Principle“改变状态的唯一方法是发出一个动作,一个描述发生了什么的对象”。

要执行此类操作,您需要使用中间件,最常见的是 redux-thunk 中间件。

这已经包含在官方的 Redux Toolkit 中了,我一般建议你去看看。

由于向您展示如何正确执行此操作会变成官方教程的 1:1 副本,请改为查看:

对于老式的“Vanilla Redux”:Redux Fundamentals, Part 6: Async Logic and Data Fetching 对于带有 Redux 工具包的“现代 Redux”:Redux Essentials, Part 5: Async Logic and Data Fetching

【讨论】:

以上是关于无法在初始渲染中显示待办事项列表的主要内容,如果未能解决你的问题,请参考以下文章

在AngularJS中编写待办事项列表时无法理解删除过程

无法从 Listview 中删除项目(待办事项列表),长按没有任何反应

在待办事项列表中隐藏/显示不同的内容并使用 JavaScript 一次显示一个内容 [关闭]

如何使用React删除待办事项列表中的项目

刷新反应组件或通量/减少中的逻辑?

JavaScript/HTML 中的待办事项列表