react学习到搭建一个全家桶的基础模板
10月,在完成了前端的负责部分,等待对接的过程中,突然想起距离2021年结束正好还剩三个月,想了想年度订的计划,遂把react 掌握一下 按照以往学习vue的方式,打开react ...
提示
React 特点
- 声明式设计 −React采用声明范式,可以轻松描述应用。
- 高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。
- 灵活 −React可以与已知的库或框架很好地配合。
- JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
- 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
- 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单
# 一、安装create-react-app 脚手架
$ cnpm install -g create-react-app
$ create-react-app my-app
$ cd my-app/
$ npm start
2
3
4
# 二、熟练 React 基础语法
# 1. 元素渲染
<!-- 项目index.js中元素初始化 -->
const element = <h1>Hello, world!</h1>;
ReactDOM.render(
element,
document.getElementById('example')
);
2
3
4
5
6
# 2. React 组件
class Welcome extends React.Component {
render() {
// 这个是组件的一个基础的传值方式,更多组件之间的通信方式放在后面的 `React组件通信` 中专门学习
const { name } = this.props
return <h1>{name}!</h1>;
}
}
import Welcome from "@/views/Welcome";
const element = <Welcome name="Hello world" />;
ReactDOM.render(
element,
document.getElementById('example')
);
2
3
4
5
6
7
8
9
10
11
12
13
14
# 3. React 条件渲染
语法其实跟javascript一致 if else && 三元表达式呀 等等
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
ReactDOM.render(
// 尝试修改 isLoggedIn={true}:
<Greeting isLoggedIn={false} />,
document.getElementById('example')
);
2
3
4
5
6
7
8
9
10
11
12
13
# 4. React 列表渲染,Keys
此处的key 与vue中渲染的key是一个用途,建议使用对象中元素,不建议index作为唯一标识
Keys 用来帮助 React 识别哪些元素发生了变化
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>{number}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('example')
);
2
3
4
5
6
7
8
9
10
# 5. React事件处理
- React 事件绑定属性的命名采用驼峰式写法,而不是小写。
- 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM 元素的写法) HTML 通常写法是:
<button onclick="activateLasers()">
激活按钮
</button>
2
3
React 中写法为:
<button onClick={activateLasers}>
激活按钮
</button>
2
3
React 阻止默认事件 必须要使用preventDefault
function ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log('链接被点击');
}
return (
<a href="#" onClick={handleClick}>
点我
</a>
);
}
2
3
4
5
6
7
8
9
10
11
12
向事件方法传递参数
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
2
# 三、掌握JSX语法
React 使用JSX代替javascript JSX是一个看起来像XML的javaScript语法扩展 使用React 不一定使用JSX,但是官方推荐~ 因为他有以下这些优点
- JSX 执行更快,因为它编译成JavaScript代码后进行了优化
- 它是类型安全的,在编译过程中就能发现错误
- 使用JSX编写模板更加简单快速
<!-- 项目index.js中元素初始化 -->
const element = <h1>Hello, world!</h1>;
ReactDOM.render(
element,
document.getElementById('example')
);
2
3
4
5
6
JSX 其他不同之处
// 1、React 推荐使用内联样式。我们可以使用 驼峰语法来设置内联样式. React 会在指定元素数字后自动添加 px
var myStyle = {
fontSize: 100,
color: '#FF0000'
};
ReactDOM.render(
<div style={myStyle}>
{/*2、JSX中不能使用if else 可以用用三元表达式*/}
{/*3、注释使用花括号的形式*/}
<h1>{i == 1 ? 'True!' : 'False'}</h1>
</div>
,
document.getElementById('example')
);
2
3
4
5
6
7
8
9
10
11
12
13
14
# 四、掌握React State
React 把组件看成是一个状态机,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。 React 里面 则是操作State来重新渲染界面(不需要操作DOM)
State类似Vue中的 data(){return {}} 内定义的数据
React中 State用法如下 注:state 只是对数据状态操作的一个称呼,state是可以改成其他符合规则的命名方式
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>现在是 {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 五、React组件API
- 设置状态:setState -> this.setState({ chart: {} });
- 替换状态:replaceState -> this.replaceState({ chart: {} });
- 设置属性:setProps
- 替换属性:replaceProps
- 强制更新:forceUpdate
- 获取DOM节点:findDOMNode
# 六、掌握React生命周期
componentWillMount 在渲染前调用,在客户端也在服务端。
componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。
componentWillReceiveProps 在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。
shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 可以在你确认不需要更新组件时使用。
componentWillUpdate 在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。
componentWillUnmount :组件卸载之前被调用
具体使用方法在后面的基础全家桶模板中会有示例
# 七、掌握props传递参数
在提到数据交互的时候不得不说到 props 与 state的区别
- State是可变的,是一组用于反映组件UI变化的状态集合
- 而Props对于使用它的组件来说,是只读的,要想修改Props,只能通过该组件的父组件修改。 在组件状态上移的场景中,父组件正是通过子组件的Props, 传递给子组件其所需要的状态。
使用props
function HelloMessage(props) {
return <h1>Hello {props.name}!</h1>;
}
const element = <HelloMessage name="Runoob"/>;
ReactDOM.render(
element,
document.getElementById('example')
);
2
3
4
5
6
7
8
默认props
lass HelloMessage extends React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
HelloMessage.defaultProps = {
name: 'Runoob'
};
const element = <HelloMessage/>;
ReactDOM.render(
element,
document.getElementById('example')
);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 八、React 组件间通信方式
# 1) props (父组件传递数据到子组件) 使用方式不再赘述
# 2) 实例方法 (父组件调用子组件方法)
在父组件中可以用refs引用子组件,使用实例如下
class TheChild extends React.Component{
myFunc(){
return '这是子组件方法'
}
}
class TheParent extends React.Component{
render(){
return (
<TheChild ref={foo =>{
this.foo = foo
}}>
)
}
componentDidMount(){
let desc = this.childRef.myFunc()
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 3)回调函数 (子组件调用父组件方法)
使用方法如下
<TheChild myFunc={this.handleChildFunc} />
// 子组件通过 this.props.myFunc() 调用父组件中的 handleChildFunc
// 最后声明 props 的类型
TheChild.propTypes = {
myFunc:React.PropTypes.func
}
2
3
4
5
6
7
8
9
关于 React的类型检查会在后面做专门的学习
# 4)同级组件通信
利用事件冒泡的机智,类似回调函数,子组件将数据回调到父组件,再由父组件传递到另外一个子组件 代码如下
// 父组件
class parentApp extends Component{
constructor() {
super()
this.state = {
info: []
}
}
// 接收子组件传递过来的数据
callback(con){
this.state.info.push(con)
this.setState({info:this.state.info})
}
render(){
return (
<div>
{/*传递给子组件的函数,在子组件中将调用onSubmit方法将数据返回过来*/}
<child1 onSubmit={this.callback.bind(this)} />
{/*child1 传递过来的值*/}
<child2 listContent={this.state.info} />
</div>
)
}
}
// 子组件1
class child1 extends Component {
handleClick() {
let inpText = this.refs.inp.value;
let txtText = this.refs.txt.value;
if (this.props.onSubmit) {
this.props.onSubmit({inpText, txtText});
}
}
render() {
return (
<div>
<input ref="inp" style={{
display: 'block',
width: 300
}}/>
<textarea ref="txt" style={{
display: 'block',
width: 300,
height: 100,
marginTop: 20
}}></textarea>
<button onClick={this.handleClick.bind(this)}>发布</button>
</div>
)
}
}
// 子组件2
class child2 extends Component {
static defaultProps = {
listContent: []
}
render() {
return (
<ul>
{
this.props.listContent.map((item, index) => {
return (
<li key={index} style={{
listStyle: 'none'
}}>
<span >{item.inpText}--</span>
<span>{item.txtText}</span>
</li>
)
})
}
</ul>
)
}
}
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 5)观察者模式
- 观察者模式是一种软件设计模式,一个对象可以在需要时发送数据到多个其他对象
- 这种方式适用于所有组件,不需要时父子组件或者平级组件。
- 一般的做法是在 componentDidMount() 里订阅事件,在 componentWillUnmount() 里取消订阅,然后在接收事件时调用 setState() 方法。
- 使用类似Vue中的Bus react中可以使用 EventEmitter 来实现
# 6)全局变量
一般不建议使用全局变量,但是确实有避免不来需要的时候,也非常的实用
建议使用window.globalVal 定义全局变量就好
END 其实vue angular react中组件中通信方式大都一致
本篇为就暂时结束,vue全家桶大家模板在下一篇中做详细说明