React再次学习(224)

ref的使用

这是react对render中元素提供的一个属性,专门用来标志mount后的元素
这个回调属性会在组件安装后立即执行。

ref字符

1
<input ref="theInput"/> //通过这个属性来对一个dom设置标志符
1
React.findDOMNode(this.refs.theInput).focus();//再通过这个方法来达到访问实体化dom的效果

ref函数

当它作为函数时,默认参数就是一个dom的对象

1
2
3
4
5
6
render: function() {
return <TextInput ref={(c) => this._input = c} />;//由于安装后立即执行,能得到对象
},
componentDidMount: function() {
this._input.focus();//对对象操作
},

bind和this

官方文档中react用bind很多;
但看他们喜欢在构造函数如此: this.handleToggleClick = this.handleToggleClick.bind(this)

我喜欢用箭头函数(es6特性,this指向定义处)直接调用

JSX嵌入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//jsx嵌入任何表达式
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
</div>
//三目运算符
<div>
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
</div>

动态组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
// Correct! JSX type can be a capitalized variable.
const SpecificStory = components[props.storyType];
return <SpecificStory story={props.story} />;
}
//默认值
<MyTextBox autocomplete />//它会默认传true的,但是官方建议不要这么写
//利用es6的解构
function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return <Greeting {...props} />;
}

html不接受字符

1
2
3
4
//有以下俩种方式解决
<MyComponent message="&lt;3" />
<MyComponent message={'<3'} />

jsx插入函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//这种用法太牛逼了,虽然不多见
function Repeat(props) {
let items = [];
for (let i = 0; i < props.numTimes; i++) {
items.push(props.children(i));//这里直接调用父类定义的函数,一个一个执行添加
}
return <div>{items}</div>;
}
function ListOfTenThings() {
return (
<Repeat numTimes={10}>
{(index) => <div key={index}>This is item {index} in the list</div>}
</Repeat>
);
}

react map组件时

  • 一个元素的key最好是这个元素在列表中拥有的一个独一无二的字符串(所以不同数组列表可以用相同key)
  • 元素的key只有在它和它的兄弟节点对比时才有意义(换句话说必须在map函数里面的组件里)
  • key只对react可见,要用其值,请将作为属性再加个传入

计算属性名

1
2
3
4
5
6
7
//多了个name属性,来对应绑定属性
//通过
this.setState({[name]: value});
//等同于如下
var partState = {};
partState[name] = value;
this.setState(partState);

控制多个元素

这个是看了官方的例子,感觉太好用了,笔记下来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}

ref用于子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} />
</div>
);
}
class Parent extends React.Component {
render() {
return (
<CustomTextInput
inputRef={el => this.inputElement = el}
/>
);
}
}

突变数据

通过shouldComponentUpdate来判断是否渲染组件,有个React.PureComponent可提供继承,它默认填写了shouldComponentUpdate函数,但是里面只是一些浅比较(对像就算被添加属性,对象的地址还是没变,导致比较为true);
深层数据则不行。
所以官方建议是Immutable来配合使用

老式的创建类和es6创建类

https://reactjs.org/docs/react-without-es6.html

Context

这个特性在官方网站上被说明为不建议使用.
优点:
跨越组件层次传递,这简直太好了,不用像props那样一个一个传,直接跨代传都可以
缺点:
这也是官方举例,当state或者setState 被调用,getChildContext也会被调用,生成新的context;
shouldComponentUpdate返回的 false 会 block 住 context,导致没有更新

另外context相当一个全局变量,难以追溯修改源.

虽然官方不建议用,但看网上建议把它当个全局固定值用,避免修改来躲避状态更新失败.

protals

当组件需要”跳出”容器(对话框,提示框,overflow:hidden z-index等),此时使用此属性

// //