我试图了解将数组中的每个项目输入为li元素的最佳方法
我很困惑,因为看起来似乎有更好的方法,或者尽管在我运行代码时它可以正常工作,但实现并不正确。
class App extends Component {
constructor(props){
super(props);
this.state = {
inputValue: '',
inputValue2: '',
todo: [],
}
}
handleInputChange(e) {
this.setState({inputValue: e.target.value})
}
mapList() {
return this.state.todo.map(x => <li>{x}</li>);
}
handleAddToDo = () => {
this.setState({
todo: [...this.state.todo, this.state.inputValue ]
})
console.log(this.state.todo);
this.setState({inputValue: ''})
this.mapList();
}
render() {
return (
<div>
<br />
<input type="text"
value={this.state.inputValue}
onChange={(e)=> this.handleInputChange(e)}
/>
<button onClick={()=> this.handleAddToDo()}>
Add to To-Do list
</button>
<ol>
{this.mapList()}
</ol>
</div>
)
}
}
答案 0 :(得分:2)
你几乎做得对。这是我的尝试。我刚删除了一些不必要的部分并将所有功能都改为箭头部分
您不必在onChange或onClick等JSX道具中调用您的函数,只需使用函数引用即可。实际上,总是这样使用它。因此,您的函数不会在每个渲染中创建。
您不需要在handleAddTodo中调用this.mapList(),因为在状态更改后,您的组件将重新渲染,mapList将再次运行。
class App extends React.Component {
state = {
inputValue: '',
todo: [],
id: 0,
}
handleInputChange = (e) =>
this.setState({ inputValue: e.target.value })
toggleCompleted = ( e ) => {
// We are caching event values since SyntheticEvent
// cannot be used asynchronously.
const checked = e.target.checked;
const id = e.target.id;
// We are mapping todos, finding related one with id
// then change its completed status to our checked value.
this.setState( prevState => ( {
todo: prevState.todo.map(
el => {
if ( el.id === Number( id )) {
return { ...el, completed: checked}
}
return el;
}
)
}))
}
mapList = () =>
this.state.todo.map(x => (
<Fragment key={x.id}>
<li>{x.value}</li>
<input type="checkbox" checked={x.completed} id={x.id} onChange={this.toggleCompleted}/>
</Fragment>
))
completedList = () => this.state.todo
.filter( el => el.completed )
.map( el => (
<Fragment key={el.id}>
<li>{el.value}</li>
<input type="checkbox" checked={el.completed} id={el.id} onChange={this.toggleCompleted} />
</Fragment>
))
// We change our todo shape here. Array of objects and it holds
// value, and mimic an id.
handleAddToDo = () =>
this.setState( prevState => (
{ todo: [...prevState.todo, { value: prevState.inputValue, completed: false, id: prevState.id + 1 }], inputValue: "", id: prevState.id + 1 }
))
render() {
console.log( this.state.todo );
return (
<div>
<br />
<input type="text"
value={this.state.inputValue}
onChange={this.handleInputChange}
/>
<button onClick={this.handleAddToDo}>Add to To-Do list</button>
<ol>
{this.mapList()}
</ol>
<p>Completed Todos</p>
<ul>
{this.completedList()}
</ul>
</div>
)
}
}