【超详细】React Native一个入门demo--ToDoList

这个实例是参照这篇文章写的:https://www.cnblogs.com/powertoolsteam/p/react-native-tutorials3.html

有需要的可以点进去看看,但是由于我是新手,基础很差所以看这个文章总是一脸懵逼,所以我决定自己重新写一下。

  • 完整代码可以在网盘里下载:https://pan.baidu.com/s/1nCuGwguOcCnIvzcED2mIOg 提取码: punn
  • 下面的内容是这个实例的每一步的分解
  • 代码的import部分和样式部分可以从上面的文件里复制

一、创建一个React Native项目

打开cmd,进入到保存项目的文件夹,执行以下语句:

react-native init 项目名称

二、真机运行项目

1.电脑通过数据线连接手机,手机进入开发者选项开启USB调试,打开cmd执行以下语句

adb devices

//若出现以下内容即连接成功
//List of devices attached
//a79dc6b4        device

2.让手机和电脑连接同一个WIFI,同时在手机的WIFI里手动设置代理,代理的IP地址写电脑的IP地址,端口是8081。

打开cmd进入项目的根目录,先后执行以下语句:

react-native start

react-native run-android

三、实践

当项目能够正常运行起来时,就可以开始动手写一个简单的demo了。

【超详细】React Native一个入门demo--ToDoList_第1张图片   【超详细】React Native一个入门demo--ToDoList_第2张图片   【超详细】React Native一个入门demo--ToDoList_第3张图片

要实现这个demo,要解决以下几个问题:

1.如何完成页面的跳转

2.如何控制组件/多选按钮的显示和隐藏

3.如何实现多选按钮两种状态的切换

整个demo的逻辑:

我们这个实例涉及四个组件,分别是App,Add,Main和ToDoListItem

【超详细】React Native一个入门demo--ToDoList_第4张图片

其中App是一个大的父组件,我们通过这个App组件访问整个应用,而且这个组件里面有一个todoList数组对象,用于存放待办事项列表;Main组件是显示的主界面;ToDoListItem组件是获取todoList中的每一项并显示出来;Add组件是添加事项的界面。

详细内容会在代码里作解释。


第一步:完成ToDoListAdd页面的编写,并把该页面挂载到App.js

(1)在项目根目录下创建一个ToDoListAdd.js文件

(2)在页面中添加以下代码 (省略了样式和import部分) :

export default class Add extends Component{

  //调用父类的构造函数,让子类继承父类的this对象,获取父类的属性
  constructor(props){ 
    super(props); 
  }

  //点击保存按钮时触发的方法,暂时不作处理  
  onPress(){  }

  render() {
    return (
        //用flexbox对页面进行布局
        
            
                返回
            
            
                
            
            
                    点击保存
                
            
        
    )
  }
}

(3)修改App.js文件,使Add组件可以显示

//引入组件
import Add from './ToDoListAdd'

export default class App extends Component{
  constructor(props){
    super(props);
  }

  render() {
    return(
      //显示该组件
      
    )
  }
}

第二步:编写ToDoListMain页面

(1)在项目根目录下创建一个ToDoListMain.js文件

(2)在页面中添加以下代码 (省略了样式和import部分) :

export default class Main extends Component{
  constructor(props){
    super(props);
    this.state={
        //设置一个状态
        isEditing:false
    };

    //bind的作用是将处理函数和指定的操作绑定在一起,操作触发时函数执行,有多种写法
    this.onEdit = this.onEdit.bind(this);
  }

    //通过setState
    //如果直接用setState修改状态可能会由于异步更新问题导致修改失败
    //所以要传入上一次状态prevState
    onEdit(){
        this.setState((prevState) => {
             return {
                isEditing: !prevState.isEditing
             }
        });
    }

  render() {
    return (
        //用flexBox布局
        
            
                添加
                待办事项
                //点击该文字会触发onEdit函数修改isEditing的值
                
                    {this.state.isEditing ? '取消' : '多选'}
                
            
        
    )
  }
}

(3)修改App.js文件,使Main组件可以显示

import Add from './ToDoListAdd'
//引入Main组件
import Main from './ToDoListMain'

……
此处内容不变
……

render() {
       return(
        //把之前显示的Add组件换成Main组件
        
) } }

第三步:实现Add页面和Main页面的跳转

(1)在App.js中添加一个状态current控制当前显示的页面,添加两个函数用于修改current值。同时要把这两个函数传给Main和Add两个子组件。

修改App.js如下:

export default class App extends Component{
  constructor(props){
    super(props);
    this.state = {
        current:'main', //current表示当前显示的页面
    }
    this.onAddItem = this.onAddItem.bind(this);
    this.onBack = this.onBack.bind(this);
  }

  //当点击‘添加’时跳转到添加页面
  onAddItem(){
    this.setState((prevState)=>{
        return{
            current:'add'
        }
    });
  }

  //在添加页面点击‘返回’回到主页面
  onBack(){
     this.setState({
        current:'main'
     });
  }

  render() {
     if (this.state.current === 'main') {
       return (
); } else { return (); } } }

 (2)在ToDoListMain页面中的“添加”加入一个onPress事件,其他代码保持不变

添加

(3)在ToDoListAdd页面中的“返回”加入一个onPress事件,其他代码保持不变

返回

说明:父组件在子组件上分别定义了onAddItem和onBack属性,子组件通过this.props获取这个属性。

 

第四步:让待办事项列表在Main组件中显示

(1)在App.js的state中添加名为todoList的数组对象

this.state = {
        current:'main', //current表示当前显示的页面
        todoList:[ //待办事项的数组,组内每一项都是一个对象
            {
                level:'info',  //通过level控制显示的样式,共有四种:info,warning,error,other
                detail:'一般的任务',  //待办事项的内容
                isChecked:false, //标记是否选中
                key:'0'  //通过key值来唯一标识
            }]
}

 (2)把上面的todoList以属性todoList传给子组件Main

在App.js的render()中对

作如下修改:

(3)在ToDoListMain.js的Main组件中添加一个

有注释的地方就是修改过的地方

render() {
    //这是获取父组件属性的另外一种写法,一种是直接'this.props.属性名',一种是用变量获取
    const {onAddItem,todoList} = this.props;

    return (
        
            

                //onPress中可以用变量onAddItem取代以前的this.props.onAddItem
                添加
                待办事项
                
                    {this.state.isEditing ? '取消' : '多选'}
                
            

            //data和renderItem是FlatList的必填属性,后者的作用是从data中挨个取出数据并渲染到列表中。
            //renderItem函数在后面会写
            
            

        
    )
  }

 (4)编写Main组件的renderItem函数,并在constructor中做绑定

…… ……
…… ……

    //显示父组件中todolist的每一项
    renderItem(item) {
      //"..."称为延展操作符,用{...item}的方式为组件传递item对象中的所有属性
      //ToDoListItem是一个组件,后面会写
      return()
    }

    onEdit(){
        this.setState((prevState) => {
             return {
                isEditing: !prevState.isEditing
             }
        });
    }

…… ……
…… ……
this.renderItem = this.renderItem.bind(this);

 

 (5)在ToDoListMain中添加一个组件ToDoListItem

class ToDoListItem extends Component{
    constructor(props){
        super(props);
    }

    render(){
        //获取从Main组件传来的item,以及item的属性
        const {item} = this.props;
        const {isChecked,detail,level} = item;
        //基础样式---圆
        const basicLevelStyle = styles.level;
        //特定样式---圆的颜色
        let specificLevelStyle;
        if(level === 'info'){
            specificLevelStyle = styles.info;
        }else if(level === 'warning'){
            specificLevelStyle = styles.warning;
        }else if(level === 'error') {
            specificLevelStyle = styles.error;
        }
         return (
               
                    
                      {detail}
                      
                    
               
         );
    }
}

第五步:点击“多选”显示复选框,点击“取消”则隐藏

(1)因为显示和隐藏都由isEditing控制,所以要在FlatList中和renderItem函数中传入该状态。

    
    
    renderItem(item) {
      return()
    }

(2)在ToDoListItem组件的render中添加以下代码实现多选框的显示隐藏:

        let url = "./img/uncheck.png";
        //定义一个小的组件checkBox,如果值为true就显示复选框,否则什么都不显示
        let checkBox = this.props.isEditing ?  :  null  ;

         return (
               
                    

                      //把这个组件加在文字的前面
                      {checkBox}

                      {detail}
                      
                    
               
         );

第六步:点击复选框切换选中和不选中状态

由于“选中”和“不选中”状态都是由Item的isChecked属性值控制的,而这个值是存放在App组件中,所以我们想要成功修改这个isChecked的值,就要回到App.js中修改才行。

(1)在App.js中定义toggleItemCheck函数并做绑定,然后在

组件中定义一个toggleItemCheck属性

    //判断该项是否被选中,并修改其isChecked值
    toggleItemCheck(item){
       //匹配item,如果不匹配则把该todo直接放入newTodos列表
       const newTodos = this.state.todoList.map(todo =>{
           if(todo !== item){
               return todo;
           }
           //如果匹配则获取该todo的所有属性,并修改其isChecked属性
           return {
               ...todo,
               isChecked:!item.isChecked
           }
       });
       this.setState({
           todoList: newTodos
       });
     }
    this.toggleItemCheck = this.toggleItemCheck.bind(this);
    
);

(2)在ToDoListMain --》Main --》renderItem函数中再次定义该属性

    renderItem(item) {
      return()
    }

(3)在ToDoListItem中调用该函数

const {toggleItemCheck,item} = this.props;
     //修改checkBox,添加onPress方法并传入当前Item值,根据isChecked的值切换两张图片
     let checkBox = this.props.isEditing ?
             toggleItemCheck(item)} >
                
            
        :  null  ;

第七步:实现Footer的显示隐藏和全选功能

到了这里其实做法跟前面都是类似的:定义函数 --》绑定函数 --》 父组件通过属性给子组件传值 --》子组件通过const或者this.props获取父组件传来的属性 --》调用函数

这部分代码不详细说明,可以直接看文件里的代码,里面会有注释。

 

你可能感兴趣的:(React,Native)