这是如何在反应中创建一个子弹点阵列

时间:2018-05-30 05:57:18

标签: reactjs

我试图了解将数组中的每个项目输入为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>
    )
  }
}

1 个答案:

答案 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>

    )
  }
}