react中的数据管理

写这篇博客是为了记录一下学习react过程中引发的对于数据管理的思考。想成为一个合格的React开发者,理解它的数据管理是深入学习它的设计理念的重要一步,对于我来说还有很长的路要走。

显然没有人会直接在react中操作DOM。

(1)基于state(状态)和props(属性)的数据管理**

这是原生React中数据管理的两个关键词。

先说一下我对state和props的理解:

React

原生React中的组件分四个不同的场景讨论:

组件内部的数据传输

React refs属性

一个应用场景:

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
import React, { Component } from 'react';

class MyComponent extends Component({

handleClick = () => {
// 使用原生的 DOM API 获取焦点
this.refs.myInput.focus();
},
render: function() {
// 当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs
return (
<div>
<input type="text" ref="myInput" />
<input
type="button"
value="点我输入框获取焦点"
onClick={this.handleClick}
/>
</div>
);
}
});

ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);

需求是点击第二个input使第一个input获得焦点,这个时候我们就不得不操作DOM了,那么我们如何在MyComponent这个组件里面获取到第一个input的DOM对象呢?

refs属性帮我们解决了这个问题。

另一种内部传递数据的方式为表单事件。

react的表单元素和HTMl中的表单元素不同。HTML中的表单元素内容取决于用户输入;React中我们可以把form表单写成受控组件。

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
class NameForm extends React.Component {

constructor(props) {
super(props);
this.state = {value: ''};
/...this.bind(this)...省略/
}

handleChange(event) {
this.setState({value: event.target.value});
}

handleSubmit(event) {
alert(this.state.value);
event.preventDefault();
}

render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text"
value={this.state.value}
onChange={this.handleChange}
/>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}

Note: Because its value is read-only, it is an uncontrolled component in React.

父组件向子组件传值

props实现

子组件向父组件传值

回调函数实现

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
import React, { Component } from 'react';
//子组件
class Child extends Component {
render(){
return (
<div>
请输入邮箱:<input onChange={this.props.handleEmail}/>
</div>
);
}
}
//父组件,此处通过event.target.value获取子组件的值

class Parent extends Component{
constructor(props){
super(props);
this.state = {
email:''
}
}

handleEmail = (event) => {
this.setState({email: event.target.value});
};
render(){
return (
<div>
<div>用户邮箱:{this.state.email}</div>
<Child name="email" handleEmail={this.handleEmail}/>
</div>
)
}
}

export default Parent;

兄弟组件之间

两个组件同属于一个父组件,且不是父子关系

如某个特殊的应用场景需要将数据挂载在父组件中,由两个组件共享:

如果组件需要数据渲染,则由父组件通过props传递给该组件;如果组件需要改变数据,则父组件传递一个改变数据的回调函数给该组件,并在对应事件中调用。

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
46
47
48
49
50
51
52
53
54
55
56
import React, { Component } from 'react';
//子组件
class Child extends Component {

render(){
return (
<div>
我是子组件邮箱:
<input
onChange={this.props.handleEmail} defaultValue={this.props.value}
/>
</div>
)
}
}

//兄弟组件

class ChildBrother extends Component {
render(){
return (
<div>
我是兄弟组件:
{this.props.value}
</div>

)
}
}

//父组件,此处通过event.target.value获取子组件的值
class Parent extends Component{

constructor(props){
super(props);
this.state = {
email:''
}
}

handleEmail = (event) => {
this.setState({email: event.target.value});
};

render(){
return (
<div>
<div>我是父组件邮箱:{this.state.email}</div>
<Child handleEmail={this.handleEmail} value={this.state.email}/>

<ChildBrother value={this.state.email}/>
</div>
);
}
}
export default Parent;

child组件的值改变后存储在父组件的state中,然后通过props传递给childBrother。

(2)基于redux的数据管理

redux

Reducer的作用:

当state没有的时候,返回initalState,有的时候根据action来状态变化,这里注意它是一个纯函数,也就是它不改变传入的state。

Store中的基本配置:

1
2
3
4
5
6
7
8
import { createStore, applyMiddleware, compose } from 'redux';
import reducer from './reducer';
import thunk from 'redux-thunk';

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)));

export default store;
-------------要说再见啦感谢大佬的光临~-------------