无法在react中的初始渲染中显示todo列表



我正在尝试使用react、redux、redux表单和firestore数据库来构建todoList,我也可以使用动作或动作创建者将todo插入数据库中,我可以获取数据库中的数据存储,但当用户第一次访问网站时,我无法在网站上显示数据,此外,当用户添加todo并提交表单时,第一个todo项显示为空白!。有人能帮我告诉我的代码出了什么问题吗?

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

动作(索引.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
});

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原理";改变状态的唯一方法是发出一个动作,一个描述发生了什么的对象;。

要做到这一点,您需要使用中间件,最常见的是redux-thunk中间件。

这已经包含在官方的Redux工具包中,我通常建议您查看。

既然向你展示如何正确地做到这一点会变成官方教程的1:1副本,那就去看看吧:

  • 代表旧式"Vanilla Redux":Redux基础知识,第6部分:异步逻辑和数据获取
  • 对于";现代Redux";使用Redux工具包:Redux Essentials,第5部分:异步逻辑和数据获取

相关内容

  • 没有找到相关文章

最新更新