react 项目练习总结

这个案例虽然简单,但是汇聚了太多的点,以至于让我这只菜鸟第一次写完这个项目后不得不总结下,接下来是我在这个项目中学到的东西

关于组件间的传值

  • 父传子----直接使用props即可

  • 字传父----由父组件通过props传递过来一个回到函数给子组件,然后在自己的触发的事件中调用

几个react编程原则

  • 状态数据要存放在各个组件公共的父组件中(方便后续传值)

  • 状态数据在哪里,处理状态的方法就写在哪里!

这个案例中所有的状态都在父组件App中,所有任何操作状态的方法都定义App组件中,只不过,谁会修改状态,就把该方法通过props传给哪个子组件。

扩展:

这里让我想到了redux,所有操作状态(prestate)的方法都定义在了reduces中,各个组件要想操作状态,就要通过action传递给reduces函数(里面包含了一些必要的数据,例如要操作的id)。

这里也能看出redux和原生react的区别:redux会使用store帮你管理状态,而原生react只能组件自己维护状态,需要跨组件通信,只能一层层传递

input:checkbox 的基础知识

  • defaultChecked 默认的checkbox的选中状态

    注意:这个属性定以后慎用,因为他只能改变一次

  • checkd 选中时值为true,没选中时值为false

    这个属性很重要!

    因为在开发中,checkbox和对应数据中的isLogin属性往往需要双向绑定,这个属性可以很方便的让我们知道checkbox当前的状态,并根据此状来控制(或受控)isLogin。

    否则我们就要自己定义一个状态字段来标识当前checkbox的状态,以前我就是这么写的,很麻烦。

事件对象(event)的几个常用属性

判断触发事件的是哪个键盘上的键,可以使用event.keyCode

加深了state 驱动页面渲染的理解

react中,可变的参数都可以放在状态里,例如本次本项目的每个li后面删除按钮的显示隐藏。

状态state如果存放的是bool值,则常会跟条件运算符结合在一起使用后

<button
   className="btn btn-danger"
   onClick={() => {this.delTodo(todoObj.id);}}
   style={{display: this.state[todoObj.id] ? "inline-block" : "none"}}
   >
   删除
</button>

react 声明周期的复习

以前只是硬背诵react的新旧声明周期,但这次真正的在项目中使用到了。

本例中使用到了两个钩子函数:componentWillMountcomponentWillReceiveProps

  componentWillMount() {
    //   在渲染吧前,先预存一个状态的默认值
    this.props.todo.map(todoObj => {
      this.setState({
        [todoObj.id]: false
      });
    });
  }

  componentWillReceiveProps(props) {
    //   每次更新前将状态写进state,先预存一个状态的默认值
    props.todo.map(todoObj => {
      this.setState({
        [todoObj.id]: false
      });
    });
  }

这里我想说一个我之前常遇到的问题,就是有时可能会给某些节点触发某个事件时增加一个state的值,但这是要注意,这可能会导致第一次渲染时,state还没有存放这些值,产生报错(获取不到某个state),这就需要在初始化时给每个item先设置一个默认的值,可以放在componentWillMount中,如果新增加的item项也要设置默认值,可以放在componentWillReceiveProps中(因为componentWillMount每个生命后期只执行一次,后面增加的他就管理不到了)。

这里我开始编程时还犯了一个错误,就是我第一次把新增item的state默认值的设置写在了componentWillUpdata中,这就反了大忌了,因为componentWillUpdata中不允许操作setState了,因为这会导致再次返回判断

shouldComponentUpdate(newProps,newState),导致程序迭代陷入死循环。

关于mouseEnter和mouseLeave时间触发时的简写

本例中有一个需求,就是划入li时,后面的删除button显示,划出时消失,这时可以采取下面的简写形式

<li
    style={{
        backgroundColor: this.state[todoObj.id] ? "#eee" : "white"
    }}
    key={todoObj.id}
    onMouseEnter={this.change(true, todoObj.id)}
    onMouseLeave={this.change(false, todoObj.id)}
    >

    ----------------------------------------
    change = (state, id) => {
        return () => {
            this.setState({
                [id]: state
            });
        };
    };

两个事件指向的处理函数一样,只是传入的参数值不同,结合高阶函数,可以写出这么简洁的形式,这时我之前怎么也想不到的。

数组的几个常用方法

项目最后的步骤一定是操作和处理数据,基本上都是直接处理数组或字符串。

几个常用的方法:

  • map (更改时常用)

  • filter (删除时常用)

解构赋值和扩展运算符

这俩es6的新增语法,使用及其广泛。

本例中,使用props传递过来的值,基本上第一步都进行了解构赋值(方便后续的操作,使其不至于太长)。

数组增加数据时,经常会和扩展运算符配合使用,并且修改isDone的值是也用到了扩展运算符。

关于组件的划分

组件划分原则,如果有的组件需要复用,则拆分拆分出来,否则就写成一坨,毕竟相互传递还是有点麻烦的。

当然也不是不能细拆,得加钱!(o(* ̄︶ ̄*)o)

posted @ 2021-05-24 22:11  wind-zhou  Views(249)  Comments(0Edit  收藏  举报