【发布时间】:2020-07-16 15:52:20
【问题描述】:
每次选中/取消选中复选框时,我都会尝试更新渲染的卡片。目前,我在试图弄清楚如何更新 todos 状态时遇到了麻烦,该状态是一个包含多个 JSON 的数组:
[{"_id":"fhrgiu34hnt","todo_description":"Lunch","todo_responsible":"1:30PM","todo_priority":"High","todo_completed":true,"todo_id":"fhrgiu34hnt"},{"_id":"fgvjhbansfgki35sn","todo_description":"Dinner","todo_responsible":"7:45PM","todo_priority":"High","todo_completed":true,"todo_id":"fgvjhbansfgki35sn"},{"_id":"sfgvhio3t58","todo_description":"Supper","todo_responsible":"10:30PM","todo_priority":"Medium","todo_completed":false}]
当通过 onChange 调用 changedBox 时值得到更新,但由于(错误地)尝试比较 componentDidUpdate 中的待办事项而没有重新渲染?当我手动刷新页面时,复选框的更新值将再次呈现。有没有办法可以更新组件 Todo 中已检查的待办事项,以便正确呈现?
这是我目前拥有的:
import React, {Component} from 'react';
import {useState, useEffect} from 'react';
import {Link} from 'react-router-dom';
import axios from 'axios';
const changedBox = (e, props) => {
const completed = e;
console.log("Inside changedBox");
console.log("Trying to update - ID: " + props.todo._id);
console.log("Checkbox is currently: " + completed);
const obj = {
todo_id: props.todo._id,
todo_description: props.todo.todo_description,
todo_responsible: props.todo.todo_responsible,
todo_priority: props.todo.todo_priority,
todo_completed: completed
};
axios.post('example.com/api', obj)
.then(response => console.log(response.data));
};
function Todo (props) {
let [t] = useState(props.todo);
console.log(t)
console.log(JSON.stringify(t));
useEffect(() => {
console.log("Inside useEffect");
axios.get('example.com/api')
.then(response => {
t = props.todo;
})
.catch(function (error) {
console.log(error);
})
})
return (
<div className="card" key={props.todo._id}>
<div className="card-body">
<input type="checkbox" id={props.todo._id} checked={props.todo.todo_completed}
onChange={event => changedBox(!props.todo.todo_completed, props)}/>
<label htmlFor={props.todo._id}/>
<div className="card-title">
<h4> {props.todo.todo_description} </h4>
<h6> {props.todo.todo_responsible} </h6>
<h6> {props.todo._id ? props.todo._id : "No ID yet"} </h6> {/* Debugging */}
<h6> {props.todo.todo_priority} </h6> {/* Debugging */}
<span
className="badge badge-info"> {props.todo.todo_completed ? "Completed" : "Not Completed"} </span>
</div>
<div className="dropdown card-options">
<Link to={"/edit/" + props.todo._id}
style={{color: 'inherit', textDecoration: 'inherit'}}>
<button className="btn-options" type="button">
<i className="fas fa-ellipsis-v"/>
</button>
</Link>
</div>
</div>
</div>
)
}
class TodosList extends Component {
_isMounted = false;
constructor(props) {
super(props);
this.state = {
todos: []
};
}
componentDidMount() {
this._isMounted = true;
axios.get('example.com/api')
.then(response => {
if (this._isMounted) {
this.setState({todos: response.data});
}
})
.catch(function (error) {
console.log(error);
})
}
componentDidUpdate(prevProps, prevState, ss) {
console.log("prevState.todos: " + prevState.todos);
console.log(JSON.stringify(prevState.todos));
console.log("Comparing JSON.stringify(this.state.todos) !== JSON.stringify(prevState.todos): " + (JSON.stringify(this.state.todos) !== JSON.stringify(prevState.todos)));
if (JSON.stringify(this.state.todos) !== JSON.stringify(prevState.todos)) {
console.log("Inside componentDidUpdate - Attempting to update!");
axios.get('example.com/api')
.then(response => {
this.setState({todos: response.data});
})
.catch(function (error) {
console.log(error);
});
}
}
componentWillUnmount() {
this._isMounted = false;
}
todoList() {
return this.state.todos.map(function (currentTodo, i) {
console.log("Todo ID: " + currentTodo._id + ", Num: " + i);
return <Todo todo={currentTodo} key={i} ind={i}/>;
});
}
render() {
return (
<div className="card-container">
<h3>List</h3>
{this.todoList()}
</div>
)
}
}
export default TodosList;
【问题讨论】:
标签: reactjs react-hooks react-props react-component