前端学习笔记(十六) --React 学习-2

今天(指两天)继续学习 React。html

1. 事件

1.1 JSX 属性写法

//普通 html:
<button onclick="printMe()"></button>

// JSX
<button onClick={printMe()}></button>复制代码

能够看到:①onclick成为了onClick。②函数不能用引号react

1.2 添加事件

在 React 中,一般是在元素初始化的时候添加监听器,而不是用 addEventListener,由于操做的基本都是 React 元素而不是 DOM 元素。数组

// function 组件
function Button(props){
  function handleClick(e){
    e.target.style.color = "red";
  }
  
  return  (<button onClick={handleClick}>A button</button>);
}复制代码

class 组件须要注意 this 的指向,由于在 onClick={handleClick} 中,handleClick 是回调函数,回调函数的 this 是指向 window 的,这是 JS 的默认行为。所以须要在构造函数中对 handleClick 进行绑定处理(这没有问题,由于原型方法比构造函数更早)。浏览器

// class 组件
class Button extends React.Component {
  constructor(props){
    super(props);
    this.handleClick = this.handleClick.bind(this); // 给 handleClick 绑定 this
                                                    // 由于该函数以后会被用做回调函数
  }
  handleClick() {
    console.log(this);
  }
  render() {
    return (
      <button onClick={ this.handleClick }> // 回调函数
        A button
      </button>
    );
  }
}复制代码

1.3 给事件添加参数

给事件处理函数添加参数有两种方法,箭头函数或者 bind。ide

<button onClick={ (e) => this.handleClick(id, e, oid) }>A button</button>
<button onClick={ this.handleClick.bind(this, id, oid) }>A button</button>复制代码

区别在于事件对象的传入(皆以上面代码的参数传入顺序为例):函数

  • 第一种方式,e 在传入的时候在什么位置,handleClick 时就在什么位置。
  • 第二种方式,e 做为最后一个参数被传入。

2. 条件渲染

条件渲染并非新的语法,只是一种使用方式。好比说建立三个组件,UserGreeting, GuestGreeting, Greeting。其中 Greeting 根据登陆状态返回剩余两个组件中的一个。学习

2.1 元素变量

把一些元素存进变量,以后再用大括号组合进其余元素,因为变量能够根据条件改变,渲染也会改变,以下图(LoginButton 和 LogoutButton 事先已建立)。this

2.2 与运算符 &&

上面在大括号里嵌入存储了元素的变量。其实因为大括号里能够嵌入表达式,还有不少种方式来写。好比与运算符 &&。3d

return ( { isLogin && <LogoutButton />} );复制代码

isLogin 为 false 的时候,后面的部分不会运行。老技巧了。component

2.3 三元运算符

没什么好说的。上面的例子能够改写成这样。

简化了许多。

2.4 null 表示不渲染

若是在 render 里返回 null,则组件不会被渲染。
可是组件的生命周期不受影响会照常进行。

3. 列表 & Key

3.1 列表

表达式能够解析列表。

  1. 普通列表:
  2. 列表里有元素:

3.2 key

若是运行上述第二个代码,控制台会有报错提示每个列表元素必须有 key 属性,以下:

  • 在控制台上是找不到这个属性的,这是用于辅助 React 来识别元素的修改的,所以每一个 key 须要在这个列表中是独一无二的字符串。
  • 若是不定义 key,会默认使用元素的索引创建 key,可是不建议这样作,会有不少问题。好比说元素顺序修改了。

3.3 key 定义的地方

key 只有放在数组上下文附近才有意义。这个很差描述,具体见文章

3.4 key 的使用

key 只能被 React 自身使用,无法访问。若是想要使用 key 的值,只能在传值给 key 的时候,传给一个别的属性,再去访问那个属性。

4. 表单

4.1 受控组件

受控组件指的是受代码控制而不是用户控制的组件。
一个普通的表单元素,会受到用户控制,每当用户输入的时候,表单的 value 就会更改。
要想接受用户的输入,就要使用组件的 state,例如:

  • 可是这样的问题在于,这只是作了一次初始化,生成一个输入框,初始值为 state 的初始值。
  • 而且此时若是在浏览器中打开会发现,输入框变成只读了,永远显示初始值,不能被更改。
  • 这样的结果是能够预测的,由于输入框的值是 this.state.name,用户输入的时候并不会更改这个值,因此显示的结果也就只会是初始值不变。
  • 虽然这不是咱们想要的,可是能够看出此时输入框的值已经彻底受代码控制而不是用户控制了,所以被称做受控组件。

4.1.1 控制值-input[type="text"]

为了控制填入的值,须要使用 onChange,每次输入框用户改变值的时候,都会更新 state:

  • e 事件被传入是能够预测的,由于 onChange 是 React 的语法,其背后仍是 js 的 onchange 函数,以上写法其实至关于:

      const btn = document.querySelector("input[type='input']");
      btn.onchange = (e) => {};复制代码

    事件函数原本就会有 e 传入,很合理。

4.1.2 textarea

原始的 textarea 的值并非 value 属性而是标签内部内容,可是 React 将其改成 value 属性,所以用法彻底和 input 同样。

4.1.3 单选/多选 select

写法以下:须要注意的几点以下:

  1. 一旦被受控,selected 就没有意义
  2. 若是要选多个值,则 value 为数组。
    1. 直接写 multiple 也行,若是要写 true,就必须加大括号
    2. handleChange 不能用 e.target.value,这个只有一个值,选择了多个返回的是 selectedOptions。不过这个属性 IE 不支持,若是要支持,参考这里的回答

4.1.4 文件输入 input[type="file"]

文件输入只能被用户控制,只能为非受控组件。

4.1.5 处理多个输入

这里指的不是 multiple select 那种。而是处理多个输入标签,如:

处理方式是加上 name 属性,handleChange 的时候根据 name 判断更改哪一个框的值。

  • 注意 checkbox 的输入值为 e.target.checked。(radio 也是)

4.1.6 value 的可编辑性

通常来讲,若是设置了 value 的值,则输入框会变成只读。但有时候设置了 value(而且没有设置 handleChange),但仍然能够编辑,那说明 value 的值为 null 和 undefined。(好比说使用某个变量的值,而后这个变量由于某种状况变成了 undefined 或者 null。)

  • value 固定为 11

  • value 为 null

4.2 非受控组件

从上面能够看出,每一种输入类型都要为之写专门的输入处理,这很麻烦。有时候只须要简单的输入而后提交,不须要作复杂的判断(好比实时判断),只须要正在提交的时候是正确的值便可。那么此时能够用非受控组件。

因为非受控组件须要使用 ref,放在以后学习。不过有一张表显示二者之间的区别,助你决定使用哪一个:

  • 上图出处为这篇文章,区别介绍的更加详细。

4.3 成熟的表单提交解决方案

官方文档推荐了 Formik,用于轻松管理复杂的表单验证。

5. 状态提高

状态提高用于多个组件共享相同的变化数据。
这里仍是参考文档来看比较好。

一些坑和心得:

  • render 中使用 if...else... 判断时,即便 if...else...囊括了全部状况,编译器也不让经过。要用三目运算符
  • 状态提高用的仍是自上而下的数据流。数据从父组件流向子组件。
  • 整个例子的流程就像是:

6. 组合

6.1 props.children

props.children 是一个特殊命名的属性:这里使用组件的方式再也不是 <Panel />,而是使用开放和闭合标签包裹了一段 html 内容。这段内容将会做为 props.children 传给子组件。

6.2 传递自定义元素

props.children 是特殊属性,传的是整个 innerHTML。若是想传一些自定义的元素的话。能够直接以相似:<MyComponent myDefined={<h1>this is a title</h1>}> 的方式传递,props 并不对值的类型有要求。JSX 语法自己也只是元素。

6.3 组合

能够经过以上语法 “组合” 成新的组件。

相关文章
相关标签/搜索