经过这两天的学习,掌握了一些React的语法规则,现在用一个小例子练习一下。需求很简单,一个备忘信息的正删改查。效果如下,我们逐步分析

wg1naHHCta.gif

1. 数据维护

我们将页面中共享的数据维护在state中,notes表示备忘信息列表;note表示与表单绑定的备忘信息值,用于收集用户的输入;index表示notes中元素的格式,用于计算备忘ID;keywords是关键字,用于过滤输入。

这里大家要明确,如果要修改state中的值请使用this.setState()函数

  class MyNote extends React.Component{
      // notes表示所有的备忘信息,note表示与表单绑定的备忘信息,index表示notes中备忘录的数量
      constructor(props){
        super(props);
        this.state = {
          notes:[],
          note:{
            content:''
          },
          index:0,
          keywords:''
        }
      }
      ...
    }

2. 页面渲染

既然数据有了,那么如何渲染到页面中呢?之前我们学过列表渲染,马上就可以派上用场了。列表渲染主要使用数组的map()函数,但是这里我们需要考虑一下过滤,用于要输入关键字,当接收到关键字后我们要对输出的内容进行过滤,那么如何过滤?如果直接修改this.state.notes将会引起不必要的麻烦,这样会造成不符合条件的数据丢失。还有一种方法就是在渲染的时候过滤。所以下面代码中我先进调用filter()进行过滤,然后调用map进行映射。

为了接受用户输入,这里用到了表单,分两部分进行,第一部分,接收备忘信息,第二部分接收关键字。向之前章节提到的,在表单项上绑定onChange事件,当用户输入改变的时候表单上的状态自动映射到state上,即可完成双向数据绑定。

 class MyNote extends React.Component{
    ...
      // 每当表单项的值发生改变的时候将表单项值的状态与state中note绑定在一起
      handleChange=(event)=>{
        let name = event.target.name;
        let val = event.target.value;
        this.setState({
          note:{
            [name]:val
          }
        })
      }
      // 绑定关键字
      handleSearch=(event)=>{
        let keywords = event.target.value;
        this.setState({
          keywords:keywords
        })
      }
      // 渲染
      render(){
        return (
          <div>
            {/*JSON.stringify(this.state)*/}
            {/* 表单*/}
            <div>
              <form onSubmit={this.handleSubmit}>
                <input type="text" name="content" value={this.state.note.content} onChange={this.handleChange}/>
                <input type="submit" value="保存"/>
              </form>
            </div>
            <div>
              <input 
                type="text" 
                placeholder="请输入关键字" 
                onChange={this.handleSearch}
                style={{border:'none','borderBottom':'1px solid #ccc'}}/>
            </div>
            {/* 列表项*/}
            <ul>
              {
                // 先过滤,再返回
                this.state.notes
                .filter(item=>item.content.indexOf(this.state.keywords)>=0)
                .map((item,index)=>{
                  return (
                    <li key={item.id}>
                      {index+1}, 
                      {item.content},
                      <a href="#" onClick={this.removeNote.bind(this,item.id)}>delete</a>
                    </li>
                  )
                })
              }
            </ul>
          </div>
        )
      }
    }

3. 保存

当用户点击保存按钮的时候,我们将state.note添加到state.notes中。注意,这里我们不能直接调用this.state.notes.push()方法来完成备忘信息的保存,因为我们无法在constructor之外的位置直接修改state中的值。添加之后我们需要清空表内容,这时候我们只需要将note恢复到初始状态即可。

      ...
      // 处理表单提交的回调函数
      handleSubmit=(event)=>{
        this.state.note.id = this.state.index + 1;
        this.state.notes.push(this.state.note);
        // 设置state值
        this.setState({
          notes:this.state.notes,
          note:{
            content:''
          },
          index:this.state.index+1
        })
        // 阻止事件默认行为
        event.preventDefault();
      }
      
    ...

4. 删除

用户在点击删除的时候需要为事件处理函数传递参数ID,我们根据ID在notes中进行匹配

      // 删除备忘
      removeNote=(id,event)=>{
        // 进行过滤
        let result = this.state.notes.filter(item=>item.id!=id)
        this.setState({
          notes:result
        })
        event.preventDefault();
      }

至此,一个具有增删改查的React小案例就完成了。有不少同学肯定着急了,感觉学到了假的React了,写代码之前不应该是先安装node,再安装create-react-app创建react工程,然后完成代码编写,这个我们在后面一点点详细说明


李春雨
325 声望188 粉丝