如何防止待办事项应用程序创建空白任务?
how can i prevent todo app from creating blank task?
我是 React 初学者,我有 3 个问题
1)如何防止创建空白任务(见附图)
2)如何为 UI 选中的任务添加删除线?
3) 为什么我会收到此错误
Warning: Each child in a list should have a unique "key" prop.
我的反应代码:
import React from "react";
import "./styles.css";
let id = 0
const Todo = props => (
<li>
<input type="checkbox" checked={props.todo.checked} onChange={props.onToggle} />
<button onClick={props.onDelete}>delete</button>
<span>{props.todo.text}</span>
</li>
)
class App extends React.Component {
constructor() {
super()
this.state = {
todos: [],
}
}
addTodo() {
const text = prompt("TODO text please!")
this.setState({
todos: [
...this.state.todos,
{id: id++, text: text, checked: false},
],
})
}
removeTodo(id) {
this.setState({
todos: this.state.todos.filter(todo => todo.id !== id)
})
}
toggleTodo(id) {
this.setState({
todos: this.state.todos.map(todo => {
if (todo.id !== id) return todo
return {
id: todo.id,
text: todo.text,
checked: !todo.checked,
}
})
})
}
render() {
return (
<div>
<div>Todo count: {this.state.todos.length}</div>
<div>Unchecked todo count: {this.state.todos.filter(todo => !todo.checked).length}</div>
<button onClick={() => this.addTodo()}>Add TODO</button>
<ul>
{this.state.todos.map(todo => (
<Todo
onToggle={() => this.toggleTodo(todo.id)}
onDelete={() => this.removeTodo(todo.id)}
todo={todo}
/>
))}
</ul>
</div>
)
}
}
export default App;
结果:
todo-list result image
- How can I prevent creating blank tasks(see attached image)
创建任务前必须检查文本是否为空字符串
addTodo() {
const text = prompt("TODO text please!")
if(text !=== ""){ // <- check here
this.setState({
todos: [
...this.state.todos,
{id: id++, text: text, checked: false},
],
})
}
}
- how to add strikethrough for checked tasks for UI?
这可以通过 css 使用 text-decoration: line-through;
轻松完成,因此,使用 属性 创建一个 class(或者您也可以内联)并且如果任务状态完成,将 class 添加到组件
.text-strike {
text-decoration: line-through;
}
<Todo className={checked ? 'text-strike' : null}}
- why i'm getting this error
每次你循环遍历一个数组来创建视图,React 都需要一些东西来区分所有的组件,所以当需要在 UI 中更新其中一个组件时(重新渲染)它确切地知道应该更新哪一个从而提高性能
{this.state.todos.map(todo => (
<Todo
onToggle={() => this.toggleTodo(todo.id)}
onDelete={() => this.removeTodo(todo.id)}
todo={todo}
key={somethingUnique} // <- you need to add this key
/>
))}
- 在
addTodo
函数中添加对空待办事项的验证,如下所示
addTodo() {
const text = prompt("TODO text please!")
if(text === undefined || text === "" || text?.trim() === ""){
alert("You are lazy!!! enter proper value.");
}else{
this.setState({
todos: [
...this.state.todos,
{id: id++, text: text, checked: false},
],
})
}
}
- 用于使用
<s>
标签 醒目的换行文本
- 你的反应渲染机制需要区分元素,它使用
key
作为区分器来轻松更新你的 for 循环中对该元素所做的任何更改,因为 dom 不代表 for 循环它是为你做的反应,这是一种让反应理解它必须维护它的界面。
因此,在您的待办事项列表中添加一个键,如下所示
<Todo
onToggle={() => this.toggleTodo(todo.id)}
onDelete={() => this.removeTodo(todo.id)}
todo={todo}
key = {todo.id}
/>
查看带有评论的更正:
import React from 'react';
let id = 0;
const Todo = (props) => (
// style based on props
<li style={{ textDecoration: props.todo.checked ? 'line-through' : ''}}>
<input
type='checkbox'
checked={props.todo.checked}
onChange={props.onToggle}
/>
<button onClick={props.onDelete}>delete</button>
<span>{props.todo.text}</span>
</li>
);
class App extends React.Component {
constructor() {
super();
this.state = {
todos: [],
};
}
addTodo() {
const text = prompt('TODO text please!');
// only do this if text has value
text && this.setState({
todos: [...this.state.todos, { id: id++, text: text, checked: false }],
});
}
removeTodo(id) {
this.setState({
todos: this.state.todos.filter((todo) => todo.id !== id),
});
}
toggleTodo(id) {
this.setState({
todos: this.state.todos.map((todo) => {
if (todo.id !== id) return todo;
return {
id: todo.id,
text: todo.text,
checked: !todo.checked,
};
}),
});
}
render() {
return (
<div>
<div>Todo count: {this.state.todos.length}</div>
<div>
Unchecked todo count:{' '}
{this.state.todos.filter((todo) => !todo.checked).length}
</div>
<button onClick={() => this.addTodo()}>Add TODO</button>
<ul>
{this.state.todos.map((todo) => (
<Todo
key={todo.id} // need a unique key using id
onToggle={() => this.toggleTodo(todo.id)}
onDelete={() => this.removeTodo(todo.id)}
todo={todo}
/>
))}
</ul>
</div>
);
}
}
export default App;
我是 React 初学者,我有 3 个问题 1)如何防止创建空白任务(见附图)
2)如何为 UI 选中的任务添加删除线?
3) 为什么我会收到此错误
Warning: Each child in a list should have a unique "key" prop.
我的反应代码:
import React from "react";
import "./styles.css";
let id = 0
const Todo = props => (
<li>
<input type="checkbox" checked={props.todo.checked} onChange={props.onToggle} />
<button onClick={props.onDelete}>delete</button>
<span>{props.todo.text}</span>
</li>
)
class App extends React.Component {
constructor() {
super()
this.state = {
todos: [],
}
}
addTodo() {
const text = prompt("TODO text please!")
this.setState({
todos: [
...this.state.todos,
{id: id++, text: text, checked: false},
],
})
}
removeTodo(id) {
this.setState({
todos: this.state.todos.filter(todo => todo.id !== id)
})
}
toggleTodo(id) {
this.setState({
todos: this.state.todos.map(todo => {
if (todo.id !== id) return todo
return {
id: todo.id,
text: todo.text,
checked: !todo.checked,
}
})
})
}
render() {
return (
<div>
<div>Todo count: {this.state.todos.length}</div>
<div>Unchecked todo count: {this.state.todos.filter(todo => !todo.checked).length}</div>
<button onClick={() => this.addTodo()}>Add TODO</button>
<ul>
{this.state.todos.map(todo => (
<Todo
onToggle={() => this.toggleTodo(todo.id)}
onDelete={() => this.removeTodo(todo.id)}
todo={todo}
/>
))}
</ul>
</div>
)
}
}
export default App;
结果: todo-list result image
- How can I prevent creating blank tasks(see attached image)
创建任务前必须检查文本是否为空字符串
addTodo() {
const text = prompt("TODO text please!")
if(text !=== ""){ // <- check here
this.setState({
todos: [
...this.state.todos,
{id: id++, text: text, checked: false},
],
})
}
}
- how to add strikethrough for checked tasks for UI?
这可以通过 css 使用 text-decoration: line-through;
轻松完成,因此,使用 属性 创建一个 class(或者您也可以内联)并且如果任务状态完成,将 class 添加到组件
.text-strike {
text-decoration: line-through;
}
<Todo className={checked ? 'text-strike' : null}}
- why i'm getting this error
每次你循环遍历一个数组来创建视图,React 都需要一些东西来区分所有的组件,所以当需要在 UI 中更新其中一个组件时(重新渲染)它确切地知道应该更新哪一个从而提高性能
{this.state.todos.map(todo => (
<Todo
onToggle={() => this.toggleTodo(todo.id)}
onDelete={() => this.removeTodo(todo.id)}
todo={todo}
key={somethingUnique} // <- you need to add this key
/>
))}
- 在
addTodo
函数中添加对空待办事项的验证,如下所示
addTodo() {
const text = prompt("TODO text please!")
if(text === undefined || text === "" || text?.trim() === ""){
alert("You are lazy!!! enter proper value.");
}else{
this.setState({
todos: [
...this.state.todos,
{id: id++, text: text, checked: false},
],
})
}
}
- 用于使用
<s>
标签 醒目的换行文本
- 你的反应渲染机制需要区分元素,它使用
key
作为区分器来轻松更新你的 for 循环中对该元素所做的任何更改,因为 dom 不代表 for 循环它是为你做的反应,这是一种让反应理解它必须维护它的界面。 因此,在您的待办事项列表中添加一个键,如下所示
<Todo
onToggle={() => this.toggleTodo(todo.id)}
onDelete={() => this.removeTodo(todo.id)}
todo={todo}
key = {todo.id}
/>
查看带有评论的更正:
import React from 'react';
let id = 0;
const Todo = (props) => (
// style based on props
<li style={{ textDecoration: props.todo.checked ? 'line-through' : ''}}>
<input
type='checkbox'
checked={props.todo.checked}
onChange={props.onToggle}
/>
<button onClick={props.onDelete}>delete</button>
<span>{props.todo.text}</span>
</li>
);
class App extends React.Component {
constructor() {
super();
this.state = {
todos: [],
};
}
addTodo() {
const text = prompt('TODO text please!');
// only do this if text has value
text && this.setState({
todos: [...this.state.todos, { id: id++, text: text, checked: false }],
});
}
removeTodo(id) {
this.setState({
todos: this.state.todos.filter((todo) => todo.id !== id),
});
}
toggleTodo(id) {
this.setState({
todos: this.state.todos.map((todo) => {
if (todo.id !== id) return todo;
return {
id: todo.id,
text: todo.text,
checked: !todo.checked,
};
}),
});
}
render() {
return (
<div>
<div>Todo count: {this.state.todos.length}</div>
<div>
Unchecked todo count:{' '}
{this.state.todos.filter((todo) => !todo.checked).length}
</div>
<button onClick={() => this.addTodo()}>Add TODO</button>
<ul>
{this.state.todos.map((todo) => (
<Todo
key={todo.id} // need a unique key using id
onToggle={() => this.toggleTodo(todo.id)}
onDelete={() => this.removeTodo(todo.id)}
todo={todo}
/>
))}
</ul>
</div>
);
}
}
export default App;