无法在初始渲染中显示待办事项列表
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【讨论】:
以上是关于无法在初始渲染中显示待办事项列表的主要内容,如果未能解决你的问题,请参考以下文章
无法从 Listview 中删除项目(待办事项列表),长按没有任何反应