今天(指两天)继续学习 React。html
//普通 html: <button onclick="printMe()"></button> // JSX <button onClick={printMe()}></button>复制代码
能够看到:①onclick成为了onClick。②函数不能用引号react
在 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> ); } }复制代码
给事件处理函数添加参数有两种方法,箭头函数或者 bind。ide
<button onClick={ (e) => this.handleClick(id, e, oid) }>A button</button> <button onClick={ this.handleClick.bind(this, id, oid) }>A button</button>复制代码
区别在于事件对象的传入(皆以上面代码的参数传入顺序为例):函数
条件渲染并非新的语法,只是一种使用方式。好比说建立三个组件,UserGreeting, GuestGreeting, Greeting。其中 Greeting 根据登陆状态返回剩余两个组件中的一个。学习
把一些元素存进变量,以后再用大括号组合进其余元素,因为变量能够根据条件改变,渲染也会改变,以下图(LoginButton 和 LogoutButton 事先已建立)。this
上面在大括号里嵌入存储了元素的变量。其实因为大括号里能够嵌入表达式,还有不少种方式来写。好比与运算符 &&。3d
return ( { isLogin && <LogoutButton />} );复制代码
isLogin 为 false 的时候,后面的部分不会运行。老技巧了。component
没什么好说的。上面的例子能够改写成这样。
简化了许多。
若是在 render 里返回 null,则组件不会被渲染。
可是组件的生命周期不受影响会照常进行。
表达式能够解析列表。
若是运行上述第二个代码,控制台会有报错提示每个列表元素必须有 key 属性,以下:
key 只有放在数组上下文附近才有意义。这个很差描述,具体见文章。
key 只能被 React 自身使用,无法访问。若是想要使用 key 的值,只能在传值给 key 的时候,传给一个别的属性,再去访问那个属性。
受控组件指的是受代码控制而不是用户控制的组件。
一个普通的表单元素,会受到用户控制,每当用户输入的时候,表单的 value 就会更改。
要想接受用户的输入,就要使用组件的 state,例如:
为了控制填入的值,须要使用 onChange,每次输入框用户改变值的时候,都会更新 state:
e 事件被传入是能够预测的,由于 onChange 是 React 的语法,其背后仍是 js 的 onchange 函数,以上写法其实至关于:
const btn = document.querySelector("input[type='input']"); btn.onchange = (e) => {};复制代码
事件函数原本就会有 e 传入,很合理。
原始的 textarea 的值并非 value 属性而是标签内部内容,可是 React 将其改成 value 属性,所以用法彻底和 input 同样。
写法以下:须要注意的几点以下:
文件输入只能被用户控制,只能为非受控组件。
这里指的不是 multiple select 那种。而是处理多个输入标签,如:。
处理方式是加上 name 属性,handleChange 的时候根据 name 判断更改哪一个框的值。
通常来讲,若是设置了 value 的值,则输入框会变成只读。但有时候设置了 value(而且没有设置 handleChange),但仍然能够编辑,那说明 value 的值为 null 和 undefined。(好比说使用某个变量的值,而后这个变量由于某种状况变成了 undefined 或者 null。)
从上面能够看出,每一种输入类型都要为之写专门的输入处理,这很麻烦。有时候只须要简单的输入而后提交,不须要作复杂的判断(好比实时判断),只须要正在提交的时候是正确的值便可。那么此时能够用非受控组件。
因为非受控组件须要使用 ref,放在以后学习。不过有一张表显示二者之间的区别,助你决定使用哪一个:
官方文档推荐了 Formik,用于轻松管理复杂的表单验证。
状态提高用于多个组件共享相同的变化数据。
这里仍是参考文档来看比较好。
一些坑和心得:
props.children 是一个特殊命名的属性:这里使用组件的方式再也不是 <Panel />,而是使用开放和闭合标签包裹了一段 html 内容。这段内容将会做为 props.children 传给子组件。
props.children 是特殊属性,传的是整个 innerHTML。若是想传一些自定义的元素的话。能够直接以相似:<MyComponent myDefined={<h1>this is a title</h1>}> 的方式传递,props 并不对值的类型有要求。JSX 语法自己也只是元素。
能够经过以上语法 “组合” 成新的组件。