我有一个待办事项列表,我正在尝试通过axios更新更新已完成/未完成的布尔值。我不确定如何最好地解决这个问题。
不幸的是,我是一个初学者,我缺乏一般的反应理解来找到正确的方法。
Dim lastcol As Long
Dim i As Integer
lastcol = Range("B5", Range("B5").End(xlToLeft)).Columns.Count + 1
For i = 0 To lastcol
Range(ActiveCell, ActiveCell.Offset(0, i)).Value =
Application.WorksheetFunction.Average(Range(Range("B5").Offset(0, i),
Range("B5").Offset(0, i).End(xlDown)))
Next i
待办事项数据结构:
class App extends Component {
constructor(props) {
super(props);
this.state = {
todoList: []
}
};
componentDidMount() {
this.refreshList();
}
refreshList = () => {
axios
.get("http://localhost:8000/api/todos/")
.then(res => this.setState({ todoList: res.data }))
.catch(err => console.log(err));
};
handleCheck = () => {
//toggle the 'completed' property and then update
};
update = item => {
axios
.put(`http://localhost:8000/api/todos/${item.id}/`, item)
.then(res => this.refreshList())
.catch(err => console.log(err));
return;
};
renderItems = () => {
const newItems = this.state.todoList
return newItems.map(item => (
<div key={item.id}>
<h6>{item.title}</h6>
<Form>
<button onClick={this.handleCheck(item)} type="submit" ></button>
</Form>
</div>
));
};
render() {
return (
<h4>ToDos</h4>
{this.renderItems()}
);
}
}
编辑:
更新:我成功用注释行成功更新了“完成”布尔值,直接更新了值。但是我知道这是不理想的方式,但是当尝试通过setState进行相同操作时,出现了意外的令牌错误,“意外的令牌,预期的(39:27)”。如何编辑setState以使其正常运行?
{
"id": 1,
"title": "Todo #1",
"description": "Lorem Ipsum",
"completed": false
}
答案 0 :(得分:1)
将待办事项的索引传递给handleCheck
函数并切换完成的值。
handleCheck = (item, index) => {
//whatever needs to happen here to updated the 'completed' property
this.setState({
todoList: [...this.state.todoList.slice(0, index),
Object.assign({}, this.state.todoList[index], {completed: !this.state.todoList[index].completed}),
...this.state.todoList.slice(index + 1)
]
});
this.update(item);
};
renderItems = () => {
const newItems = this.state.todoList || [];
return newItems.map((item, index) => (
<div key={item.id}>
<h6>{item.title}</h6>
<Form>
<button onClick={() => this.handleCheck(item, index)} type="submit" ></button>
</Form>
</div>
));
};
简化版本,创建您的todoList副本并使用索引更新todo。
handleCheck = (item, index) => {
const copy = JSON.parse(JSON.stringify(this.state.todoList));
copy[index].completed = !copy[index].completed;
this.setState({
todoList: copy
});
this.update(item);
};
演示
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component {
constructor() {
super();
this.state = {
name: 'React',
todoList: [
{
"id": 1,
"title": "Todo #1",
"description": "Lorem Ipsum",
"completed": false
},
{
"id": 2,
"title": "Todo #2",
"description": "Lorem Ipsum",
"completed": false
},
{
"id": 3,
"title": "Todo #3",
"description": "Lorem Ipsum",
"completed": false
}
]
};
}
handleCheck = (item, index) => {
const copy = JSON.parse(JSON.stringify(this.state.todoList));
copy[index].completed = !copy[index].completed;
this.setState({
todoList: copy
});
// this.update(item);
};
renderItems = () => {
const newItems = this.state.todoList || [];
return newItems.map((item, index) => (
<div key={item.id}>
<h6>
{item.completed ? <strike>{item.title}</strike> : item.title}</h6>
<button onClick={() => this.handleCheck(item, index)} >Submit</button>
</div>
));
};
render() {
return (
<div>
<p>
Todos
</p>
{this.renderItems()}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
</script>
答案 1 :(得分:0)
您没有在任何地方调用该更新函数,而在按钮单击时调用了该句柄单击函数。
因此,只需将项目作为句柄检查函数中的参数,然后从那里调用更新函数,它将起作用
handleCheck = (item) => {
this.update(item)
}
答案 2 :(得分:0)
class App extends Component {
constructor(props) {
super(props);
this.state = {
todoList: []
}
};
componentDidMount() {
this.refreshList();
}
refreshList = () => {
axios
.get("http://localhost:8000/api/todos/")
.then(res => this.setState({ todoList: res.data }))
.catch(err => console.log(err));
};
handleCheck = (item) => {
this.update(item)
// Make your backend do the update
};
update = item => {
axios
.put(`http://localhost:8000/api/todos/${item.id}/`, item)
.then(res => this.refreshList())
.catch(err => console.log(err));
return;
};
renderItems = () => {
const newItems = this.state.todoList
return newItems.map(item => (
<div key={item.id}>
<h6>{item.title}</h6>
<Form>
// See this line ( how to bind functions )
<button onClick={this.handleCheck.bind(this, item)} type="submit" ></button>
</Form>
</div>
));
};
render() {
return (
<h4>ToDos</h4>
{this.renderItems()}
);
}
}
答案 3 :(得分:0)
Junius L.建议使用此解决方案,但我不得不更改/简化handleCheck函数。因此,这里有更改的解决方案和我的经验,也许这对某人有所帮助。如果我的结论不正确,也请发表评论。
学习#1:不使用setState()不要更新状态 学习#2:您无法在第二级状态下更新属性。而是将其复制到局部变量中,进行所需的更新,然后将整个状态设置为新状态。
handleCheck = (item, index) => {
const items = this.state.todoList
items[index].completed = !items[index].completed
this.setState({todoList:items});
this.update(item);
};
renderItems = () => {
const newItems = this.state.todoList || [];
return newItems.map((item, index) => (
<div key={item.id}>
<h6>{item.title}</h6>
<Form>
<button onClick={() => this.handleCheck(item, index)} type="submit" ></button>
</Form>
</div>
));
};