javascript - REACT/REDUX 编辑item和添加item后key的两个问题
问题描述
我有两个问题。我会尽可能多地解释它。
我在我的代码中添加了项目编辑功能,不幸的是,当我接受更改时,我的项目并没有改变。add(几乎),remove 选项可以正常工作。但是,更新选项不会发送请求。
第二个问题是,在添加编辑元素功能的代码稍作更改后,我添加元素的代码有点坏了。完成表单并发送后,添加了元素,但添加了没有ID码的错误:
Warning: Each child in a list should have a unique "key" prop.
刷新页面后,问题消失,之前添加的项目已经有ID并正确显示。
问题 1
TaskDetail.js 组件
import React, { Component } from "react";
import { connect } from "react-redux";
import { getTask, updateTask } from "../../actions/tasks";
import { Redirect } from "react-router-dom";
class TaskDetail extends Component {
constructor(props) {
super(props);
this.state = {
title: "",
description: "",
date: "",
hours: null,
};
}
componentDidMount() {
this.props.getTask(this.props.match.params.id);
setTimeout(() => this.update(), 50);
}
update = () => {
console.log("STATE UPDATE");
const { title, description, date, hours } = this.props.task[0];
this.setState({
title: title,
description: description,
date: date,
hours: hours,
});
};
onChange = (e) => {
this.setState({
[e.target.name]: e.target.value,
});
};
onSubmit = (e) => {
console.log("UPDATE REQUEST");
const task = {
title: this.state.title,
description: this.state.description,
date: this.state.date,
hours: this.state.hour,
};
this.props.updateTask(this.props.task.id, task);
};
render() {
const { title, description, date, hours } = this.state;
return (
<div className="card mt-5">
<div className="card-header">
<span>ID: {this.props.match.params.id}</span>
</div>
<form
className="card-body"
onSubmit={this.props.updateTask.bind(
this.props.match.params.id,
this.state
)}
>
<div className="form-group">
<label>Title</label>
<input
type="text"
className="form-control"
name="title"
onChange={this.onChange}
value={title || ""}
/>
</div>
<div className="form-group">
<label>Description</label>
<textarea
type="text"
className="form-control"
name="description"
onChange={this.onChange}
value={description || ""}
/>
</div>
<div className="date-hours-form">
<div className="form-group">
<label>Date</label>
<input
type="date"
className="form-control"
name="date"
onChange={this.onChange}
value={date || ""}
/>
</div>
<div className="form-group">
<label>Hours</label>
<input
type="number"
className="form-control"
name="hours"
onChange={this.onChange}
value={hours || ""}
/>
</div>
</div>
<div className="form-group">
<button type="submit" className="btn btn-block btn-suc">
EDIT TASK
</button>
</div>
</form>
</div>
);
}
}
const mapStateToProps = (state) => ({
task: state.tasks.task,
isLoading: state.tasks.isLoading,
});
export default connect(mapStateToProps, { getTask, updateTask })(TaskDetail);
任务Action.js
// UPDATE TASK
export const updateTask = (id, task) => (dispatch) => {
console.log(`ID: ${id} TASK: ${task}`);
axios
.put(`/api/tasks/${id}/`, task)
.then((response) => {
dispatch({
type: UPDATE_TASK,
payload: task,
});
})
.catch((err) => console.log(err.response));
};
任务归约器.js
import {
GET_TASKS,
DELETE_TASK,
CREATE_TASK,
GET_TASK_REQUEST,
GET_TASK_SUCCESS,
UPDATE_TASK,
} from "../actions/types.js";
const initialState = {
tasks: [],
task: {},
isLoading: false,
};
export default function (state = initialState, action) {
switch (action.type) {
case GET_TASKS:
return {
...state,
tasks: action.payload,
};
case DELETE_TASK:
return {
...state,
tasks: state.tasks.filter((task) => task.id !== action.payload),
};
case CREATE_TASK:
return {
...state,
tasks: [...state.tasks, action.payload],
};
case GET_TASK_REQUEST:
console.log("TASK GET PENDING");
return {
...state,
isLoading: action.payload.loading,
};
case GET_TASK_SUCCESS:
console.log("TASK GET SUCCESS");
return {
...state,
task: state.tasks.filter((task) => task.id === action.payload.data.id),
isLoading: action.payload.loading,
};
case UPDATE_TASK:
console.log("TASK UPDATED");
return {
...state,
task: {},
};
default:
return state;
}
}
问题二
任务列表.js
import React, { Component, Fragment } from "react";
import { connect } from "react-redux";
import { getTasks, deleteTask, getTask } from "../../actions/tasks";
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
export class Tasks extends Component {
static propTypes = {
tasks: PropTypes.array.isRequired,
getTasks: PropTypes.func.isRequired,
deleteTask: PropTypes.func.isRequired,
};
render() {
return (
<div className="card card-tasks card-body mt-3">
<table className="table table-striped">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Title</th>
<th scope="col">Date</th>
<th scope="col">Hours</th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{this.props.tasks.map((task) => (
<Fragment key={task.id}>
<tr>
<th>{task.id}</th>
<td>{task.title}</td>
<td>{task.date}</td>
<td>{task.hours}</td>
<td>
<Link
to={{
pathname: `/edit/${task.id}`,
state: { id: task.id },
}}
className="btn btn-primary"
>
DETAIL
</Link>
</td>
<td>
<button
onClick={this.props.deleteTask.bind(this, task.id)}
className="btn btn-danger"
>
DELETE
</button>
</td>
</tr>
</Fragment>
))}
</tbody>
</table>
</div>
);
}
}
const mapStateToProps = (state) => ({
tasks: state.tasks.tasks,
});
export default connect(mapStateToProps, { getTasks, deleteTask, getTask })(
Tasks
);
解决方案
推荐阅读
- javascript - 无法在反应客户端和快速服务器之间建立 websocket 连接
- javascript - 如何从 ionic3 中的“https://www.gstatic.com/webp/gallery3/1.png”之类的图像 url 转换为 base64 字符串?
- sql - 有没有办法将嵌套的json数据插入到sql server中
- cuda - 安装 pytorch-gpu 时 nvcc 和 clang 不能很好地协同工作
- python - “将从 wav 音频文件中提取的区域转换为 Flac 音频文件” python 在 Django 中使用 FFMPAG
- delphi - 没有显示我犯的错别字和错误
- javascript - AngularJS单击事件不适用于温泉ui按钮
- java - 从 recyclerview 中获取详细数据,意图在 extends Fragment 中
- java - 仅旋转数组中某些元素的最快方法是什么?
- javascript - 如何访问具有日期格式的对象属性?