React
文章目录
react项目移植出现的问题
当把我的react项目移植到另一台电脑时,因为要npm install 安装依赖库,但是对于采用npm install会带来一些库的版本问题,当时找了很多方法才解决,解决方法就是很简单:是采用yarn包管理工具,yarn会自己解决一些库的版本问题,使得在新环境中不会因版本问题报错
1. react是什么
React是一个用于构建用户界面的js库,
React主要作用是来写html页面,或构建web应用
从MVC角度,react仅仅是视图层V,也就是只负责视图的渲染,而并非提供了完整的M和C。
2. React的特点:
\1. 声明式,你只需要描述UI什么样子,跟写html页面一样
这里是用到了jsx语法创建react元素:
Const jsx = <div>react帅哦</div>;
\2. 基于组件开发,组件是react中最重要的内容,组件就是页面中的一部分内容
\3. 学习一次,随便使用,可以开发网页,手机app、vr技术
react 高性能的体现:虚拟DOM
我们以前是操作真实的dom,通过document.querySelector()的方式。这样的过程实际上是先读取html的dom结构,将结构转换为变量,再进行操作。而reactjs定义了一套变量形式的虚拟dom模型(jsx+state),这是一种虚拟dom,一切操作和换算直接在变量中(也可以说一切操作都是在虚拟dom中进行的),state等数据修改完之后再转化为真实DOM渲染到浏览器页面中,这样就减少了操作真实DOM,性能更高了,和主流的MVC有本质的区别,并不和真实DOM树打交道。
其实虚拟DOM的真实价值从来都不是为了以提升性能为第一位,而是采用虚拟DOM可以使得react元素(虚拟DOM)脱离浏览器的束缚,让其可以跨平台地运行在其他Android端、vr环境中。我们开发React都是在面向虚拟DOM进行开发
3.React cli创建react项目:
npm init react-app my-app
4. React使用:
导入react、react-dom包
import React from 'react';
import ReactDOM from 'react-dom';
// 利用createElement()函数创建react元素,较为复杂
// const title = React.createElement('h1', null, 'react是你hi');
// 使用jsx的方式创建react元素
const title = <h1>react 你好帅哦!</h1>;
// 利用reactDOM进行渲染
ReactDOM.render(title, document.querySelector('#wh'));
5. JSX语法:
JSX并不是标准的ECMAScript语法,他是ES的语法扩展。
它需要使用babel编译处理之后,才能再浏览器环境中使用,而react-cli中已经默认配置了,所以在脚手架中就可以使用这种语法。
注意点:
react元素的属性名驼峰命名法
使用小括号包括jsx
const title = (<h1 className="w">react 你好帅哦!<span /> </h1>);
jsx总结
1.jsx是react的核心内容
2.jsx表示在js代码中写HTML节后,是React生命是的体现
3.使用jsx配合嵌入的js表达式、条件渲染、列表渲染可以描述任意UI结构
4.推荐使用className的方式给jsx添加样式
5.react完全是利用js语言自身的能力编写UI,而不是造轮子增强HTML功能。(这也是react和vue的区别,vue可以利用v-for、v-model指令以造轮子来增强html,而react是纯手写js代码实现渲染)
react特色:只要能用到js的地方就绝对不会增加一个新的语法
6. react组件
使用函数创建组件
// 第一种创建方式,同归js的函数创建组件
// 组件的首字母必须大写
function Hello() {
return (
<div>hello,我是你 !</div>
);
}
// 第二种创建组件方式类组件,使用ES6的class类创建的组件
class Hello2 extends React.Component {
render() {
return (
<div>hello2,react还是你 !</div>
)
}
}
绑定事件
//在类组件中添加事件,需要用到this才能触发函数
class Hello2 extends React.Component {
handlePrevent(e) {
// e为事件对象,react中的事件对象叫做合成事件(对象)
e.preventDefault();
console.log("react 我被阻止啦");
}
render() {
return (
<div>
<div>hello2,react还是你 !</div>
<a href="http://www.baidu.com" onClick={this.handlePrevent}>我是React</a>
</div>
)
}
}
//在函数组件中,不需要用this
function Hello() {
function handleClick() {
console.log(1);
}
return (
// 事件绑定
<div onClick={handleClick}>hello,我是你 !</div>
);
}
7.有状态组件和无状态组件
- 函数组件称为无状态组件,类组件称为有状态组件。
- 函数组件没有自己的数据,也叫做没有自己的状态,它只负责静态页面的渲染
- 而类组件有自己的状态,负责更新UI页面,负则把数据渲染到页面中,让页面动起来
state的基本使用
状态(state)即数据,是组件内部的私有数据,只能在组件内部使用,state的值是一个对象,表示一个组件中可以含有多个数据,这些数据构成一个对象
class Count extends React.Component {
/* constructor() {
super();
this.state = {
count1: 1
}
} */
// 简化语法
state = {
count1: 0
}
render() {
return (
<div>
有状态组件{this.state.count1}
</div>
)
}
}
setState()修改状态(数据)
- 状态是可变的;
- 语法:this.setState({要修改的数据})
- 注意:不要直接修改state中的值,这是错误的,想要修改数据就必须在setState()中进行修改
class Count extends React.Component {
/* constructor() {
super();
this.state = {
count1: 1
}
} */
// 简化语法
state = {
count1: 0
}
// 这里只能使用箭头函数(this指向这个类),如果不用箭头函数,那么里面的this指向此handleAdd函数调用者,或者使用call()修改this指向
handleAdd() {
//调用setState()
this.setState({ count1: this.state.count1 + 1 });
}
render() {
return (
<div>
有状态组件:{this.state.count1}
<button onClick={this.handleAdd}>+</button>
</div>
)
}
}
8. 表单处理
受控组件:
步骤:
- 在state中添加一个状态,作为表单元素的value值(控制表单元素值的来源)
- 给表单绑定change事件,将表单元素的值设置为state的值(控制表单元素值的变化)
- React将state与表单元素值value绑定到一起,由state的值来控制表单元素的值
- 受控组件:其值收到React控制的表单元素
非受控组件
借助于ref,使用原生DOM方式来获取表单元素值。
ref:ref就是用来获取DOM或组件的一个属性
使用步骤:
- 调用react.createRef()方法创建一个ref对象
- 把创建好的ref对象添加到文本框中国
- 通过ref对象的获取到文本框的值
class Whh extends React.Component {
constructor() {
super();
// 创建ref
this.myRef = React.createRef();
}
getTxt = () => {
console.log(this.myRef.current.value);
}
render() {
return (
//以后this.myRef就代表表这个DOM框了
<div>
<input type="text" ref={this.myRef}></input>
<button onClick={this.getTxt}>点我查看文字</button>
</div>
)
}
}
9. 组件间的数据传输props
组件是封闭的,要接收外部组件的数据要通过props来实现
prop的作用:
接收传递给组件的数据
-
第一步:传递数据:给组件标签添加属性
// 渲染APP3组件(用于学习prop相关的知识点),传递数据:name、age ReactDOM.render(<App3 name="react" age="23" />, document.querySelector("#prop1"))
-
第二步:接收数据:
class App3 extends React.Component {
// props是个对象
// 在类组件中使用this.props来获取传递过来的props数组,在函数组件时,在函数的参数中传递props参数
// name = this.props.name;
props1 = this.props.name;
render() {
console.log(this.props); //props是个数组
return (<div>props:{this.props1}</div>)
}
}
props的特点
- 可以给组件传递任意类型的数据
- props是个只读的对象,只能读取属性的值,是不能修改的!
- 注意:在使用类组件是,如果写了构造函数constructor(),应该将props传递给super(),否则,无法在构造函数中获取到props
constructor(props) {
super(props);
console.log(props);
}
组件之间通信的三种方式
父组件----》子组件
子组件----》父组件
兄弟组件之间通信
父向子组件传递数据:
- 第一步:父组件提供要传递的state数据
- 第二步:子组件接收数据
class Child extends React.Component {
render() {
return (
// 父向子传递第二步:从父组键接收到的props数据
<div>{this.props.name}</div>
)
}
}
class Parent extends React.Component {
state = {
name: "react"
}
render() {
return (
<div>
// 父向子传递第一步:向子组件传递来自父组件的state数据
传递数据给子组件<Child name={this.state.name} />
</div>
)
}
}
子组件向父组件传递数据:
思路:利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数
- 第一步:父组件提供一个回调函数(用于接收数据)
- 第二步,通过props传递回调函数
- 第三步:子向父通过prop接收到的函数来向父组件传递参数
class Child extends React.Component {
render() {
console.log(this.props);
// 子向父第三步:子向父通过prop接收到的函数来向父组件传递参数
this.props.getmsg(" ");
return (
// 父向子传递第二步:从父组键接收到的props数据
<div>{this.props.name}</div>
)
}
}
class Parent extends React.Component {
// 子向父传递数据第一步,定义回调函数:
getChildMsg = (msg) => {
console.log("接收到的数据", msg);
}
state = {
name: "react"
}
render() {
return (
/* 父向子传递第一步:向子组件传递来自父组件的state数据 */
// 子向父传递数据第二步,通过props传递回调函数
<div >
传递数据给子组件<Child name={this.state.name} getmsg={this.getChildMsg} />
</div>
)
}
}
兄弟组件之间传递数据:
将共享状态提升到最近的公共组件中,由公共组件管理这个状态
思想:变量提升
公共组件负责:1.提供共享状态 2.提供操作共享状态的方法
要通讯的子组件只需要通过props接收状态和操作状态的方法
Context实现跨组件传递数据
使用Context实现跨组件传递数据(比如主题,语言等)
使用步骤:
-
调用React.createContext()创建Provider(用于提供数据)和Consumer(用于消费数据)两个组件。
const { Provider, Consumer } = React.createContext()
-
// 第二步:用Provider包裹,即作为父节点
// 第二步:用Provider包裹,即作为父节点 <Provider> <div> <Nodes /> </div> </Provider>
-
// 第三步:设置value属性,表示要传递的数据,提供数据也就是通过value传递
<Provider value="react ">
<div>
<Nodes />
</div>
</Provider>
- 通过Consumer组件接收数据
<div>
<Consumer>
{
data => <div>data</div>}
</Consumer>
</div>
props高级
props.children属性
children属性:表示组件标签的子节点。当组件标签有子节点是,props就会有该属性,值可以是任意值(文本、React元素、组件、函数)
class Hello3 extends React.Component {
render() {
// props的children属性
conso