reactjs - 在数组(状态)中添加的待办事项对象不会立即反转
问题描述
我正在前端使用 React-redux 创建 Todo CRUD 应用程序。当我将一个新的 todo 对象添加到 todos 列表(状态中的数组)时,我希望将新的 todo 呈现在最顶部,而不是最后一个。我只是将组件连接到 redux 状态(待办事项列表)并反转它。它起作用了,虽然不是立即,而是在一段时间后。我想问题出在生命周期中。索引组件连接到 redux 状态。渲染生命周期创建标记,映射到状态数组,然后 Componentdidmount 触发从而更新状态,然后重新渲染发生,因此视图。这不是立即发生,而是在几毫秒后发生。但我不确定也很困惑,因为我尝试了另一种生命周期方法,但没有结果......
todos 组件列表
Index.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { todoList } from '../actions/todoActions';
import TableRow from './TableRow';
class Index extends Component {
componentDidMount() {
this.props.todoList();
};
tabRow() {
return this.props.allTodos.map(user => {
return <TableRow obj={user} key={user._id} />
});
}
render() {
return (
<div>
<h3 align="center">Todo List</h3>
<table className="table table-striped" style={{ marginTop: 20 }}>
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
<th>Task</th>
<th colSpan="2">Action</th>
</tr>
</thead>
<tbody>
{ this.tabRow() }
</tbody>
</table>
</div>
)
}
};
const mapStateToProps = state => ({
allTodos: state.todo.todos.reverse()
});
export default connect(
mapStateToProps,
{ todoList }
)(Index);
创建待办事项
import React from 'react';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { registerTodo } from '../actions/todoActions';
class Create extends React.Component {
constructor(props) {
super(props);
this.userChangeHandler = this.userChangeHandler.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
name: '',
surname: '',
task: ''
};
}
userChangeHandler(e) {
this.setState({
[e.target.name] : e.target.value
});
};
onSubmit(e) {
e.preventDefault();
const newUserTodo = {
name: this.state.name,
surname: this.state.surname,
task: this.state.task
};
this.props.registerTodo(newUserTodo, this.props.history);
};
render() {
return(
<div style={{marginTop: 10}}>
<h3>Add New Task</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Add Name: </label>
<input
type="text"
name="name"
className="form-control"
onChange={this.userChangeHandler}
/>
</div>
<div className="form-group">
<label>Add Surname: </label>
<input
type="text"
name="surname"
className="form-control"
onChange={this.userChangeHandler}
/>
</div>
<div className="form-group">
<label>Add Todo Task: </label>
<input
type="text"
name="task"
className="form-control"
onChange={this.userChangeHandler}
/>
</div>
<div className="form-group">
<input type="submit" value="Create Todo" className="btn btn-primary"/>
</div>
</form>
</div>
)
}
};
export default connect(
null,
{ registerTodo }
)(withRouter(Create));
待办事项
TableRow
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { deleteTodo } from '../actions/todoActions';
class TableRow extends Component {
render() {
return (
<tr>
<td>
{this.props.obj.name}
</td>
<td>
{this.props.obj.surname}
</td>
<td>
{this.props.obj.task}
</td>
<td>
<Link to={'/edit/'+this.props.obj._id} className="btn btn-primary">Edit</Link>
</td>
<td>
<button onClick={this.props.deleteTodo.bind(this, this.props.obj._id)} className="btn btn-danger">Delete</button>
</td>
</tr>
);
}
};
const mapStateToProps = state => ({
allTodos: state.todo.todos
});
export default connect(
mapStateToProps,
{ deleteTodo }
)(TableRow);
行动
export const registerTodo = (userTodo, history) => dispatch => {
axios
.post('/api/users/add', userTodo)
.then(res => {
dispatch(setTodo(userTodo));
history.push('/index');
})
.catch(err => console.log(err));
};
export const setTodo = todo => {
return {
type: ADD_TODO,
payload: todo
};
};
export const todoList = () => dispatch => {
axios
.get('/api/users')
.then(res => {
dispatch(getTodos(res.data));
});
};
export const getTodos = todos => {
return {
type: GET_TODOS,
payload: todos
}
};
减速机
const initialState = {
todos: []
};
export default function(state = initialState, action) {
switch(action.type) {
case ADD_TODO:
return {
...state,
todos: [...state.todos, action.payload]
};
case GET_TODOS:
return {
...state,
todos: [...action.payload]
};
default:
return state;
}
}
解决方案
老实说,我没有正确理解这个问题。但从我收集的信息来看,您希望新的待办事项放在其他待办事项的前面。这可以通过切换 ADD_TODO 减速器中的位置来完成。
case ADD_TODO:
return {
...state,
todos: [action.payload, ...state.todos]
};
编辑:获取 todos 的 api 调用可能不一样,只是将其附加到末尾。在这种情况下,如果可以的话,你应该在那里处理它。(或)您应该在从 api 获取数据后自行执行此操作。由于这是在 componentDidMount() 中完成的,因此在第一次渲染后调用它会有延迟。添加微调器是一种解决方法。
推荐阅读
- itext - 升级到 iTextSharp v5.5.8+ 后 pdf 无效
- c# - 数据库设计(RPG项目增强)
- python - tkinter 中的数组状态
- ajax - 错误 ajax 无法将参数传递给 Spring Controller
- ios - 变量从另一个 swift 文件更改其值后返回 nil 值
- android - 从 Android 到 Cassandra 的远程查询
- php - Wordpress PHP 调用 MySQL 程序挂起
- oop - Kotlin 中的 OVERRIDE_BY_INLINE
- java - JAXB marshal to string 在不同计算机上的工作方式不同
- spring - Spring Boot Actutor Web 指标 - 禁用(或分组)http_server_requests_seconds_sum