所以我有这个课:
class TaskList extends Component {
constructor(props) {
super(props);
this.state = {
tasks: []
};
this.handleDelete = this.handleDelete.bind(this);
this.handleEdit = this.handleEdit.bind(this);
}
componentWillMount() {
axios.get("/api/all").then(result => {
this.setState({
tasks: result.data
});
});
}
handleDelete(id) {
axios.delete(`/api/${id}`).then(res => {
axios.get("/api/all").then(tasks => {
this.setState({
tasks: tasks.data
});
});
});
}
handleEdit(id, updatedTask) {
axios.put(`/api/${id}`, updatedTask).then(res => {
axios.get("/api/all").then(tasks => {
console.log(tasks);
this.setState({
tasks: tasks.data
});
})
.catch(err => {
console.log(err);
})
}).catch(err => {
console.log(err);
});
}
render() {
const { tasks } = this.state;
console.log('list render');
console.log(this.state);
return (
<div className="container">
<div className="title row col-lg-6 mx-auto">
<div className="col-sm-4">{"Date"}</div>
<div className="col-sm-4">{"Task"}</div>
<div className="col-sm-4">{"Status"}</div>
</div>
{tasks.map(i => (
<div className={`${i._id} task mx-auto col-lg-6`}>
<div className={`${i._id} row`}>
<Task
key={i._id}
id={i._id}
title={i.title}
date={i.date}
complete={i.complete}
handleDelete={this.handleDelete}
handleEdit={this.handleEdit}
/>
</div>
</div>
))}
</div>
);
}
}
任务组件
class Task extends Component {
constructor(props) {
super(props);
this.state = {
date: new Date(props.date),
complete: props.complete
};
this.handleDelete = this.handleDelete.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleDelete() {
this.props.handleDelete(this.props.id);
}
handleClick() {
const updatedTask = {
title: this.props.title,
complete: !this.state.complete
};
this.setState({ complete: !this.state.complete });
this.props.handleEdit(this.props.id, updatedTask);
}
render() {
const { title } = this.props;
const { date, complete} = this.state;
return (
<>
<div className='col-sm-4'>
{date.getFullYear() + "/" + date.getMonth() + "/" + date.getDate()}
</div>
<div className="col-sm-4">{title}</div>
<div className="col-sm-3" onClick={this.handleClick}><Status complete={complete}/></div>
<div className="col-sm-1" onClick={this.handleDelete}><IconClose /></div>
</>
);
}
}
状态组件
const Status = props => {
console.log(props);
return (
<>
{props.complete ? (
<i className="far fa-check-square" />
) : (
<i className="far fa-square" />
)}
</>
);
};
我遇到的问题是我的handleEdit上的问题,我没有使组件使用更新的任务列表重新呈现。 handleDelete函数可以正常工作并更新屏幕,但不能进行编辑。
我一直以为setState会导致重新渲染,然后我也尝试了forceUpdate,但是它也不起作用。
任何帮助都会很棒。
答案 0 :(得分:0)
我认为这里的问题是道具进入国家的分支。
在Task
内部,代码调用this.props.handleEdit(this.props.id, updatedTask)
,它将数据发送到父组件TaskList
。该handleEdit
函数更新了tasks
的状态键TaskList
。
但是,当每个任务的完成状态传递给Task
时,它从props
分支到其自己的组件状态:
this.state = {
...
complete: props.complete
};
constructor
函数仅被调用一次; props.complete
再也无法更新状态。我的建议是使用从TaskList
传递过来的道具,除非出于特殊原因必须将其完整性值存储在Task
内。
React文档解释了这种常见的反模式:
问题在于,这既不必要(您可以直接使用
this.props.color
),又会产生错误(对颜色道具的更新不会反映在状态中)。仅当您有意忽略道具更新时才使用此模式。