我已经在reactjs中编写了todo列表的开头,并且正在寻求改进todos如何添加到状态的功能。目前,我将put中的值连接到处于状态的数组中,然后拼接掉所选的li元素。添加第一个待办事项时似乎有点儿麻烦。我应该使用反应不变性助手来实现这一目标吗?似乎过度杀戮增加了另一件可以在普通js中实现的东西。
//Input component
const Input = props => {
return (
<div className="form-group">
<input
className="form-control"
value={props.value}
onChange={props.update}
type="text"
/>
<button className="btn btn-default" onClick={props.handleClick}>
Add Todo
</button>
</div>
);
};
//display list of todos
const Displaytodo = (props) => {
const todolist = props.todo;
const listItems = todolist.map((todo, index) =>
<li
className={
props.highlight ? 'list-unstyled todoItem highlight' : 'list-unstyled todoItem '
}
key={index}>
{todo}
<div
onClick={props.removeTodo.bind(this, index)}
className="removeTodo">
<i className="fa fa-trash" />
</div>
<div onClick={props.changeHighlight.bind(this,index)} className="checkTodo">
<i className="fa fa-check-circle" onClick={props.highlight} />
</div>
</li>
);
return <ul className="todos">{listItems}</ul>;
};
//controlled state component
class Layout extends React.Component {
constructor() {
super();
this.state = { text: "Hello", todo: [], highlight: false };
}
update(e) {
this.setState({ text: e.target.value });
}
handleClick() {
const text = this.state.text;
if (text.length > 0) {
this.setState(
{ todo: this.state.todo.concat(text), text: "", highlight: false },
function() {
console.log(this.state.todo);
}
);
} else {
alert("please enter something");
}
}
removeTodo(e) {
this.state.todo.splice(e, 1);
this.setState({ todo: this.state.todo });
}
changeHighlight(index, e) {
const highlight = this.state.highlight;
this.setState(prevState => ({
highlight: !prevState.highlight
}));
}
render() {
return (
<div className="container">
<div className="row">
<div className="col-md-4 col-md-offset-4">
<div className="wrapper">
<h1>Todo List</h1>
<Input
value={this.state.text}
update={this.update.bind(this)}
handleClick={this.handleClick.bind(this)}
/>
<Displaytodo
removeTodo={this.removeTodo.bind(this)}
todo={this.state.todo}
changeHighlight={this.changeHighlight.bind(this)}
highlight={this.state.highlight}
/>
</div>
</div>
</div>
</div>
);
}
}
const app = document.getElementById("app");
ReactDOM.render(<Layout />, app);
https://codepen.io/mhal12/pen/MomWVg
此外,当用户点击绿色勾选时,它会通过切换类突出显示该行&#39;突出显示&#39;关闭和打开,但在控制台中它给出了一个错误。链接到
https://facebook.github.io/react/docs/error-decoder.html?invariant=94&args[]=onClick&args[]=boolean
答案 0 :(得分:1)
只需删除onClick
上的<i className="fa fa-check-circle" onClick={props.highlight} />
。
至于每个todo
的突出显示,它有点复杂。您必须在每个id
上设置todo
,然后将id
传递给changeHighlight
功能。您必须从全局状态中删除突出显示,并在每个highlight
上分配todo
布尔值。然后你必须相应地显示todos
。
removeTodo
函数的相同内容,您传入id
以在父组件中删除它。
这里是完整的代码:
const Input = props => {
return (
<div className="form-group">
<input
className="form-control"
value={props.value}
onChange={props.update}
type="text"
/>
<button className="btn btn-default" onClick={props.handleClick}>
Add Todo
</button>
</div>
);
};
const Displaytodo = (props) => {
const changeHighlight = function(id) {
props.changeHighlight(id);
}
const removeTodo = function(id) {
props.removeTodo(id);
}
const todolist = props.todo;
const listItems = todolist.map((todo, index) =>
<li
className={
todo.highlight ? 'list-unstyled todoItem highlight' : 'list-unstyled todoItem '
}
key={todo.id}>
{todo.text}
<div
onClick={removeTodo.bind(event, todo.id)}
className="removeTodo">
<i className="fa fa-trash" />
</div>
<div onClick={changeHighlight.bind(event, todo.id)} className="checkTodo">
<i className="fa fa-check-circle" />
</div>
</li>
);
return <ul className="todos">{listItems}</ul>;
};
class Layout extends React.Component {
constructor() {
super();
this.state = {text: "Hello", todo: []};
}
update(e) {
this.setState({ text: e.target.value });
}
handleClick() {
const text = this.state.text;
if (text.length > 0) {
this.setState(
{ todo: this.state.todo.concat({
id: this.state.todo.length + 1,
text: this.state.text,
highlight: false
}), text: ""},
function() {
console.log(this.state.todo);
}
);
} else {
alert("Please enter something");
}
}
removeTodo(id) {
let todos = this.state.todo;
for (let i = 0; i < todos.length; i++) {
let todo = todos[i];
if (todo.id == id) {
todos.splice(i, 1);
}
}
this.setState({ todo: todos });
}
changeHighlight(id) {
let todos = this.state.todo;
for (let i = 0; i < todos.length; i++) {
let todo = todos[i];
if (todo.id == id) {
todos[i].highlight = !todos[i].highlight;
}
}
this.setState({
todo : todos
});
}
render() {
return (
<div className="container">
<div className="row">
<div className="col-md-4 col-md-offset-4">
<div className="wrapper">
<h1>Todo List</h1>
<Input
value={this.state.text}
update={this.update.bind(this)}
handleClick={this.handleClick.bind(this)}
/>
<Displaytodo
removeTodo={this.removeTodo.bind(this)}
todo={this.state.todo}
changeHighlight={this.changeHighlight.bind(this)}
/>
</div>
</div>
</div>
</div>
);
}
}
const app = document.getElementById("app");
ReactDOM.render(<Layout />, app);