微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决无法在反应的初始渲染中显示待办事项列表

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

App.js

async_parallel([some_functionOne,some_functionTwo,some_functionThree]);
debug(results);      // prints "results" object successfully without problems

function async_parallel(functions_to_run) {
  let promises = functions_to_run.map(function_to_run => promisfy(function_to_run));
  const results = await Promise.all(promises);
  return results;
}

Todo.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)

动作(index.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

TodoReducer.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'}
}

reducers.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;
    }
}

解决方法

在您的 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 副本,因此请查看:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。