React 手把手入门编写 Todo List 应用

1,813 阅读3分钟

写在前面

这东西已经有很多大佬们写过了,就不多班门弄斧了。主要使用这个例子入门 React ,包括 state、props、组件间通信这些基础内容。Todo List 应用通常都被列为能入手开发项目的 Hello World 典范。

state

state 是组件在渲染自身时用到的数据。我们可以通过 this.state 获得自己在 state 里定义的数据。可以使用 this.setState() 方法更新 state,当 this.setState() 被调用时,React 会调用组件的 render() 方法重新渲染组件。需要提到的是 this.setState() 是异步的。

props

翻阅资料都没有看到 props 的具体定义,props 总结就相当于我们写 HTML 时的标签属性。它是我们进行组件开发时暴露在外面的,在外面定义形如 ,在组件内部就可以通过 this.props.data 取到从外面传入的 data 的内容了 。

组件间通信

React 组件间通信

Todo List 应用

我们使用 create-react-app 创建工程。删除 App.js 生成的东西,修改成这样。

import React, {Component} from 'react';
import './App.css';

class App extends Component {  
  render() {
    return (
      <div style={{margin: '10px'}}></div>
    );
  }
}

export default App;

在 src 目录下创建 components 文件夹,并在里面创建 TodoList 文件夹,里面创建 TodoList 文件。代码如下。

import React, {Component} from 'react';

class TodoList extends Component {
  render() {
    return (
      <div>
        TodoList
      </div>
    );
  }
}


export default TodoList;

将 TodoList 导入到 App.js 里, 在 App.js 里初始化 list 数据,并传递给 TodoList 组件

import React, {Component} from 'react';
import './App.css';
import TodoList from "./components/TodoList/TodoList";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [
        {
          text: 'do duck'
        }
      ]
    }
  }
  
  render() {
    return (
      <div style={{margin: '10px'}}>
        <TodoList list={this.state.list}/>
      </div>
    );
  }
}

export default App;

在 components 文件夹下创建 TodoItem 文件夹,里面创建 TodoItem 文件。代码如下。

import React, {Component} from 'react';

class TodoItem extends Component {
  render() {
    return (
      <li>
        <p style={{fontSize: '20px', lineHeight: 1.5}}>
          {this.props.text}
        </p>
      </li>
    );
  }
}

export default TodoItem;

导入到 TodoList。

import React, {Component} from 'react';
import TodoItem from "../TodoItem/TodoItem";

class TodoList extends Component {
  render() {
    return (
      <div>
        <TodoItem />
      </div>
    );
  }
}

export default TodoList;

在 components 文件夹下创建 TodoInput 文件夹,里面创建 TodoInput 文件。并初始化输入框的 state 与事件绑定代码如下。

import React, {Component} from 'react';

class TodoInput extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: ''
    }
  }

  handleChange(e) {
    this.setState({
      value:e.target.value
    })
  }

  render() {
    return (
      <div>
        <input type="text"
               value={this.state.value}
               onChange={ e => this.handleChange(e)}
        />
        <button onClick={() => this.handleAddClick()}>add</button>
      </div>
    );
  }
}

export default TodoInput;

将 TodoInput 导入 App.js

import React, {Component} from 'react';
import './App.css';
import TodoList from "./components/TodoList/TodoList";
import TodoInput from "./components/TodoInput/TodoInput";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [
        {
          text: 'do duck'
        }
      ]
    }
  }

  render() {
    return (
      <div style={{margin: '10px'}}>
        <TodoInput />
        <TodoList list={this.state.list} />
      </div>
    );
  }
}

export default App;

为输入框添加按钮绑定事件。我们事件需要写在和 state 同级下的 App.js ,方便操作 state ,并传入组件,让组件内的 button 调用。

// App.js
import React, {Component} from 'react';
import './App.css';
import TodoList from "./components/TodoList/TodoList";
import TodoInput from "./components/TodoInput/TodoInput";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [
        {
          text: 'do duck'
        }
      ]
    }
  }

  handleAddClick(text) {
    this.setState({
      list: [...this.state.list, {text}]
    })
  }

  render() {
    return (
      <div style={{margin: '10px'}}>
        <TodoInput onclick={text => this.handleAddClick(text)}/>
        <TodoList list={this.state.list} />
      </div>
    );
  }
}

export default App;
// TodoInput.js 组件
import React, {Component} from 'react';

class TodoInput extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: ''
    }
  }

  handleAddClick() {
    // eslint-disable-next-line no-unused-expressions
    this.props.onclick ? this.props.onclick(this.state.value) : null
    this.setState({
      value: ''
    })
  }

  handleChange(e) {
    this.setState({
      value:e.target.value
    })
  }

  render() {
    return (
      <div>
        <input type="text"
               value={this.state.value}
               onChange={ e => this.handleChange(e)}
        />
        <button onClick={() => this.handleAddClick()}>add</button>
      </div>
    );
  }
}

export default TodoInput;

为 list 添加删除事件,删除我们直接做成点击添加的内容就删除。也是一样需要在 App.js 定义事件,并传入组件,让组件调用。

// App.js
import React, {Component} from 'react';
import './App.css';
import TodoList from "./components/TodoList/TodoList";
import TodoInput from "./components/TodoInput/TodoInput";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [
        {
          text: 'do duck'
        }
      ]
    }
  }

  handleAddClick(text) {
    this.setState({
      list: [...this.state.list, {text}]
    })
  }
  handleDeleteClick(id) {
    let list = this.state.list;
    list.splice(id, 1)
    this.setState({
      list
    })
  }

  render() {
    return (
      <div style={{margin: '10px'}}>
        <TodoInput onclick={text => this.handleAddClick(text)}/>
        <TodoList list={this.state.list}
                  onDelete={ id => this.handleDeleteClick(id)}
        />
      </div>
    );
  }
}

export default App;
// TodoList.js 组件
import React, {Component} from 'react';
import TodoItem from "../TodoItem/TodoItem";

class TodoList extends Component {

  render() {
    return (
      <ul>
        {
          this.props.list && this.props.list.map((item, idx) => {
            return (
              <TodoItem key={idx}
                        text={item.text}
                        onClick={() =>
 this.props.onDelete ? this.props.onDelete(idx) : null}
              />
            )
          })
        }
      </ul>
    );
  }
}

export default TodoList;

到此,npm run start 打开页面,就完成了。

代码仓库: gitee.com/plus1515/re…