逐渐认识
1.jsx格式将内容包裹在圆括号中,避免自动插入分号陷阱。
2.jsx可以当作普通对象进行使用,如返回值、变量、传参等。
3.JSX 防止注入攻击: React DOM 在渲染所有输入内容之前,默认会进行转义。 它可以确保在你的应用中,永远不会注入那些并非自己明 确编写的内容。所有的内容在渲染之前都被转换成了字符 串。这样可以有效地防止 XSS(cross-site-scripting, 跨 站脚本)攻击。 (这里说的不是很清楚,去查一下)
4.babel会将jsx转译成一个名为react.createElement()函数调用
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
// ===
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
//之后返回了对象
//如下是简化过的结构
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};
5.除了函数式组件,还有继承class实现的组件
6.组件名称必须以大写字母开头(和原生dom标签分开)
7.提取组件原则:
(1)多次使用
(2)组件本身足够复杂
8. props 不能被更改,state 就是用来改变的
这么说就理解了,并不!
props传过来的某个属性如果是多个对象的数组,赋值操作时简单的解构赋值并不是深拷贝,一定要注意,对里面的对象也要再一次进行解构赋值(为什么用解构赋值“...”,因为简单)
9.Class 组件应该始终使用 props
参数来调用父类的构造函数
10.一个标签里面没有内容,你可以使用 /> 来闭合标签
11.JSX 里的 class 变成了 className,而 tabindex 则变为 tabIndex
props
prop类型不是字符串时,需要用花括号,如:
style={{color:"red"}} //里面的花括号代表是个对象
state
state不可以直接修改,必须要用setState方法进行修改赋值
因为setState是异步的,所以不能保证同步执行,故在依赖state的值的时候,要让其接收一个函数而不是对象,这样可以保证拿到最新的值。
state和props
props是其他组件传入的
state:1、随时间变化,且不是props传入的
2、 由state和props计算得到的也不是state
setState
是异步的函数,如果参数是函数意味着,每次获取的state都是最新的,但是不要忘记,它依然是异步处理的。
参数
this.setState((state, props) => {
return {counter: state.counter + props.step};
});
class无this解决
1.bind
可以在构造函数里bind,也可以在回调函数onClick={this.handleClick.bind(this)}
2.class field
3.回调函数用箭头函数
不推荐直接在回调函数中使用箭头函数,每次都会创建不同的回调函数,因为它作为prop进行传参时,可能会进行额外的重新渲染
组件
事件处理的传参
第一种:箭头函数,事件对象必须显式的进行传递
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
第二种:bind , 事件对象以及更多的参数将会被隐式的进行传递
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
react的子组件传参给父组件主要采用回调函数内传参。
不能这样写:
<button onClick={onDeleteRow(id)}>Delete Row</button>
这样渲染完成后就直接执行,而不是点击后执行了。
这样:
<button onClick={()=>onDeleteRow(id)}>Delete Row</button>
或者包装起来:
onDeleteRow = () => onDeleteRow(id)
--------------------------------------------
<button onClick = { onDeleteRow }>Delete Row</button>
包含
父组件中留空,便于其他插入
{props.children}
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children} //--------props.children--------
</div>
);
}
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">//--------start---------
Welcome
</h1>//-------end----------
</FancyBorder>
);
}
{props.other}
function SplitPane(props) {
return (
<div className="SplitPane-left">
{props.left} //-----props.left------
</div>
);
}
function App() {
return (
<SplitPane
left={<Contacts /> }//-----h------
/>
);
}
key值
元素的 key 只有放在就近的数组上下文中才有意义
经验:在 map()
方法中的元素设置 key 属性,如下图:
第一种:
第二种:
使用的 key 在其兄弟节点之间应该是独一无二的。然而,它们不需要是全局唯一的
组件不能读取key属性,需要使用其他自定义属性进行保存
一些不同
className="badge badge-pill badge-info m-2"
style={{ width: 50, fontSize: "24px" }}
事件处理的写法的不同:
<button onclick="activateLasers()">
<button onClick={activateLasers}>
阻止默认行为
function handleSubmit(e) {
e.preventDefault();//必须显示声名阻止默认行为
console.log('You clicked submit.');
}
<form onSubmit={handleSubmit}>
条件渲染
1、判断语句
函数组件里用判断语句控制return
2、&&或者||
ex2=1
ex2&&example:返回example
ex2=0
ex2&&example:返回ex2
ex2=1
ex2||example:返回ex2
ex2=0
ex2||example:返回example
3、三目运算符
不仅可以用于数值,也可以用于组件
阻止渲染
使用条件判断,return null,但是组件生命周期依然存在
生命周期
constructor()
getInitialState()// es6不会用到
getDefaultProps()// es6不会用到
componentWillMount()
render()//这个之后,dom就已经建成啦
componentDidMount() { }//挂载,在此时setState影响性能,除非渲染依赖于节点位置大小
//卸载
componentWillUnmount() { }
受控和非受控组件
在受控组件上指定 value
的 prop 会阻止用户更改输入
受控组件:如input textarea select,由react管理
非受控组件:如input(file),由dom节点管理
default
赋予组件一个初始值,但是不去控制后续的更新
<input type="checkbox">` 和 `<input type="radio">` 支持 `defaultChecked`
`<select>` 和 `<textarea>` 支持 `defaultValue
总结:有value,不用defaultvalue,必需handle方法
没有value,用defaultvalue
组件defaultProps
例如:
NavBar.defaultProps={
itemsLen:0
}
constructor
when
需要继承且有除props之外的值,如:
class C extends A {
constructor (props) {
super(props)
this.state = { val: '' }//constructor 中写了 state,
}
}
//或者
class C extends A {
constructor (props) {
super(props) // 此时可以省略
}
state = { val: '' }
}