如何建立设计一个公司网站,哈尔滨网站建设公司名字,怀化同城网站,淄博 网站推广一、类组件的props属性
组件中的数据#xff0c;除了组件内部的状态使用state之外#xff0c;状态也可以来自组件的外部#xff0c;外部的状态使用类组件实例上另外一个属性来表示props
1、基本的使用
在components下创建UserInfo组件
import React, { Component } from…一、类组件的props属性
组件中的数据除了组件内部的状态使用state之外状态也可以来自组件的外部外部的状态使用类组件实例上另外一个属性来表示props
1、基本的使用
在components下创建UserInfo组件
import React, { Component } from react
import ../assets/css/userinfo.scss
export default class UserInfo extends Component {render() {return (div classNameinfo-boxh3{this.props.title}/h3 div姓名:{this.props.name}/divdiv年龄:{this.props.age}/divdiv性别:{this.props.gender1?男:女}/divdiv爱好{this.props.hobby.join(、)}/div /div)}
}
在App.jsx中引用组件并且传递数据到组件的内部
import React, { Component } from react
import UserInfo from ./components/UserInfo
export default class App extends Component {constructor(){super()this.state{users:[{title:教师信息,name:翟吉喆,age:38,gender:1,hobby:[爱打游戏,爱读书]},{title:学生信息,name:张资源,age:24,gender:1,hobby:[爱写js,爱UI设计]},
{title:班主任信息,name:王玉倩,age:28,gender:0,hobby:[爱唱歌,爱学习]}]}}render() {const {users}this.statereturn ({users.map((item,index)UserInfo key{index} {...item}/)}/)}
}
2、props的默认值
React的props的默认值设置有两种方法 类名.defaultProps{key:value}
export default class UserInfo extends React.Component{}
UserInfo.defaultProps{title:暂无标题,name:暂无名称,age:0,gender:1,hobby:[暂无兴趣],birthday:new Date(),avatar:http://old.woniuxy.com/page/img/head_picture/0.jpg
} static defaultProps{key:value}(推荐)
export default class UserInfo extends React.Component{static defaultProps{title:暂无标题,name:暂无名称,age:0,gender:1,hobby:[暂无兴趣],birthday:new Date(),avatar:http://old.woniuxy.com/page/img/head_picture/0.jpg}
}
3、props验证器[了解]
配置React验证器的步骤 下载prop-types依赖包
yarn add prop-types 引入prop-types
import PropTypes from prop-types 配置验证器 配置验证器也有两种方法 类名.propTypes{key:value} export default class UserInfo extends React.Component{}
UserInfo.propTypes{age:PropTypes.number.isRequired
} static propTypes{key:value} export default class UserInfo extends React.Component{static propTypes{age:PropTypes.number.isRequired}
} 4、props的只读性 总结 通过props传递进来的基本类型组件内部不能直接更改如果更改就会报如下错误 通过props传递进来的引用数据不能直接更改如果更改会报如下错误 通过props传递进来的引用数据类型可以更改引用数据类型的属性
二、React插槽
在React中实现插槽需要我们自己来实现 主要用到props.children
三、组件的生命周期
生命周期指的就是从组件的加载初始化-数据的改变-组件的卸载阶段。描述的就是组件从创建到死亡的阶段react的生命周期中提供了很多个生命周期钩子函数来方便我们操作。
react的生命周期主要分为以下的几个步骤 挂载阶段组件数据的初始化及组件数据的渲染 运行阶段这个节点是最长的阶段主要用户对组件的数据进行修改状态改变以及重绘 卸载阶段这个阶段也是销毁阶段组件运行完成后或者从页面中移除那么组件就应该被销毁。这个阶段我们可以执行一些资源的回收性能优化的代码可以在这里设计。
组件的生命周期流程图
React lifecycle methods diagram 1、组件挂载阶段
组件的挂载阶段也是组件创建-数据初始化-数据渲染的过程。接下来通过代码来演示执行的流程。
1.1 constructor构造器执行的阶段
构造执行那就意味着组件正在被创建并且数据也可以在这里初始化。
通常在 React 中构造函数仅用于以下两种情况 通过给 this.state 赋值对象来初始化内部 state 为事件处理函数绑定实例
如果不初始化 state 或不进行方法绑定则不需要为 React 组件实现构造函数。
import React, { Component } from reactexport default class LifeCycle extends Component {constructor(props){super(props)this.state{count:0}this.incrementthis.increment.bind(this)console.log(执行constructor组件正在创建和初始化);}increment(){this.setState({count:this.state.count1})}render() {console.log(调用render方法开始执行数据渲染);return (divh1React生命周期全过程/h1{this.state.count}button onClick{this.increment}/button/div)}
}
输出的结果为
执行constructor组件正在创建和初始化
调用render方法开始执行数据渲染先执行constructor构造器将数据初始化其中props和state的数据就会被加载。接着执行render函数来渲染。
1.2 componentDidMount函数执行
界面渲染完毕DOM挂载完毕的一个通知类似于vue组件中的created,我们可以在这个生命周期做
很多事情。 获取DOM节点 发送请求获取后台数据 设置定时器、延时器等等 绑定全局事件例如document的点击事件等等 async componentDidMount(){console.log(componentDidMount);const {data:{movies}}await axios.get(https://www.fastmock.site/mock/4441a79ad5f884f83b784cf4c588bdb6/movies/getHotMovies)}
2、组件更新阶段
每当组件的props或者state变化之后都会导致组件的更新我们可以使用钩子函数在组件更新之前或者之后做一些逻辑操作。
2.1、创建shouldComponentUpdate钩子函数来拦截数据修改
shouldComponentUpdate(){return false;
}
定义在重新render之前被调用可以返回一个布尔值来决定一个组件是否更新 如果返回false那么前面的流程都不会被触发。这个方法默认的返回值都是true。
这里我们再来完成一个功能就是将外部传递进来的数据赋给内部变量data,当点击按钮的时候每次增加1
import React, { Component } from react
import axios from axios
export default class LifeCycle extends Component {constructor(props){super(props)this.state{title:props.title}}changeTitle(){this.setState({title:计数器演示})}render() {console.log(调用render方法开始执行数据渲染);return (divh1{this.state.title}/h1button onClick{this.changeTitle}更改标题/button/div)}shouldComponentUpdate(nextProps,nextState){console.log(this.state.title----------nextState.title);return true}
}
但是从控制台的显示结果来看每次点击之后都是上次的数据如果要想得到更改后的数据我们可以使用如下参数来解决这个问题
参数nextProps代表更改后的props值nextState代表更改过后的state值。我们可以获取到这个数据进行判断
shouldComponentUpdate(nextProps,nextState){console.log(this.state.data----nextState.data);return true;
}
控制台显
示效果如下所示
2.3 componentDidUpdate钩子函数来执行通知。
componentDidUpdate(){console.log(数据修改成功);
}
3、组件卸载阶段
componentWillUnmount在组件被卸载和销毁之前调用的方法可以在这里做一些清理的工作。我们要完成组件的卸载那需要创建两个组件在父组件中引入子组件当条件为true的时候就加载组件条件为false的时候就卸载组件。
export default class ParentCom extends Component {state {isShow:true}changePanel (){this.setState({isShow:false})}render() {return (divh1ParentComponent/h1{this.state.isShow ChildCom/}{/* {this.state.isShow } */}button typebutton onClick{this.changePanel}点击切换/button/div)}
}
花括号中嵌入逻辑与 () 运算符。它可以很方便地进行元素的条件渲染是我们的短路运算符一旦this.state.boo的值为false那后面ChildCom的组件就不会渲染。
当点击按钮我们动态修改isShow的值然后判断条件false组件就卸载。
export default class ChildCom extends Component {render() {return (divh2ChildComponent/h2/div)}componentWillUnmount(){console.log(ChildCom组件正在卸载);}
}
一旦组件卸载那就执行componentWillUnmount钩子函数完成调用那我们可以完成清理工作。
执行结果为
ChildCom组件正在卸载
4、资源清理
在componentWillUnmount钩子函数中我们可以执行一些资源清理工作。比如事件解绑定时器清除等等工作。
先在ChildCom子组件里面定义事件和定时器等等代码。
componentDidMount(){this.timer setInterval(function(){console.log(定时器执行);},1000);
}
在componentDidMount组件里面设置一个定时器我们在父组件里面将组件卸载。但是定时器依然在执行所以所以在组件卸载的时候我们需要清楚定时器。
componentWillUnmount(){console.log(ChildCom组件正在卸载);clearInterval(this.timer);
}
执行完组件的卸载那定时器就被清除。
四、兄弟组件通信 状态提升 事件总线 发布订阅模式
1、状态提升
React中的状态提升概括来讲就是将多个组件需要共享的状态提升到他们最近的父组件上再在父组件上改变这个状态然后通过props分发给子组件
1新建Child.jsx组件
import React, { Component } from react
import ./son.css
export default class Son extends Component {render() {return (div classNamesonboxh2儿子/h2button onClick{(){this.props.callback(通过父亲给妹妹1万元)}}发送/button/div)}
}
2新建Parent.jsx组件
import React, { Component } from react
import ./parent.css
import Son from ./Son
import Daughter from ./Daughter
export default class Parent extends Component {state{fromChildMsg:}render() {return (div classNameboxSon classNamec1 callback{(msg){//接收儿子给的信息console.log(接受儿子的信息,msg);//然后将这个信息更新到状态中this.setState((){return {fromChildMsg:msg}},(){console.log(this.state.fromChildMsg)})}}/SonDaughter classNamec2 cmsg{this.state.fromChildMsg}/Daughter/div)}
}
3新建Daughter.jsx
import React, { Component } from react
import ./daughter.css
export default class Daughter extends Component {render() {return (div classNamedaughterboxh2女儿/h2div{this.props.cmsg}/div/div)}
}
2、事件总线方式
兄弟之间传递参数我们有多种方案本节中我们就给大家带来。基于事件总线的方式来设计
EventBus 又称为事件总线。在Vue中可以使用 EventBus 来作为沟通桥梁的概念就像是所有组件共用相同的事件中心可以向该中心注册发送事件或接收事件所以组件都可以上下平行地通知其他组件但也就是太方便所以若使用不慎就会造成难以维护的灾难因此才需要更完善的Vuex作为状态管理中心将通知的概念上升到共享状态层次。
但在React中没有EventBus的概念可以通过 node events模块进行模拟在React中可以依赖一个使用较多的库 events 来完成对应的操作。
1安装events
yarn add events
2创建事件中心
新建一个文件MyEventListener.js文件用于作为事件中心。
import { EventEmitter } from events;
export default new EventEmitter();
我们只需要引入EventEmitter对象将这个对象实例化过后返回出去调用的时候执行对应的API就可以完成事件的绑定和通知
events常用的API 创建EventEmitter对象eventBus对象 发出事件eventBus.emit(事件名称, 参数列表); 监听事件eventBus.addListener(事件名称, 监听函数) 移除事件eventBus.removeListener(事件名称, 监听函数)
3监听事件
import React, { Component } from react
import MyEventListener from ./MyEventListenerexport default class Borther1 extends Component {state{className:web05}//在组件完毕后就监听dataChange事件componentDidMount(){MyEventListener.addListener(dataChange,this.changeData);}//当组件卸载的时候就移除事件监听componentWillUnmount(){MyEventListener.removeListener(dataChange,this.changeData);}changeData(params){this.setState({className:params});}render() {return (divh2兄弟1/h2p数据为:{this.state.className}/p/div)}
}
在生命周期函数里面绑定事件监听和移除事件监听当事件中心里面加入了dataChange事件当前组件就能监听到接着执行我们绑定的changeData。
4发送事件
在Brother2组件里面我们添加一个按钮往事件中心发出一个dataChange事件并将值传递给调用者
import React, { Component } from react
import MyEventListener from ./MyEventListenerexport default class Borther2 extends Component {changeData(){MyEventListener.emit(dataChange,web08);}render() {return (divh2兄弟2/h2button onClick{this.changeData}修改数据/button/div)}
}
其中emit这个API就可以完成事件发送。这样就可以完成兄弟组件之间的参数传递当然事件总线这种设计模式可以应用在任何组件之间。实现跨组件通信。
3、发布与订阅模式
1定义订阅者
//创建一个observer.js文件
const observer{list:[],subscribe(callback){this.list.push(callback)},dispatch(data){this.list.forEach(item {item(data)});}
}
export default observer
2定义子组件用来发送数据
import React, { Component } from react
import ./son.css
import observer from ../observer
export default class Son extends Component {render() {return (div classNamesonboxh2儿子/h2button onClick{(){observer.dispatch(兄弟姐妹们我给每个人200元) }}发送/button/div)}
}
3定义子组件用来接受数据
import React, { Component } from react
import ./daughter.css
import observer from ../observer
export default class Daughter extends Component {state{fromMsg:}componentDidMount(){observer.subscribe(data{this.setState((){return{fromMsg:data}})})}render() {return (div classNamedaughterboxh2女儿/h2div{this.state.fromMsg}/div/div)}
}
五、表单处理
表单的处理从表单中获取内容
vue中如果获取表单的内容:v-model:是一个双向绑定的指令react不是一个双向绑定的
1、受控表单
1.1、什么是受控组件
在 HTML 中表单元素如input、 textarea 和 select之类的表单元素通常自己维护 state并根据用户输入进行更新。而在 React 中可变状态mutable state通常保存在组件的 state 属性中并且只能通过使用 setState()来更新。
我们可以把两者结合起来使 React 的 state 成为“唯一数据源”。渲染表单的 React 组件还控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。
1.2、受控组件的使用步骤 在state中添加一个状态name
state{name:
} 我们在input标签里面定义了value属性这个属性就是文本框的值将state对象里面的name绑定到文本框里面 input value{this.state.name}/ onChange是必须要的这个函数相当于绑定了一个事件当数据发生变化的时候可以执行你绑定的函数handlerName input value{this.state.name} onChange{this.handleName}/ 定义bindName函数将文本框的值动态绑定赋值给state对象
handleName(e){this.setState({name:e.target.value})
}
参数e代表事件对象可以通过e来获取到target目标对象通过value值来获取文本框的值。
2、非受控表单
有时使用受控组件会很麻烦因为你需要为数据变化的每种方式都编写事件处理函数并通过一个 React 组件传递所有的输入 state。当你将之前的代码库转换为 React 或将 React 应用程序与非 React 库集成时这可能会令人厌烦。在这些情况下你可能希望使用非受控组件, 这是实现输入表单的另一种方式。
在大多数情况下我们推荐使用 受控组件 来处理表单数据。在一个受控组件中表单数据是由 React 组件来管理的。另一种替代方案是使用非受控组件这时表单数据将交由 DOM 节点来处理。
要编写一个非受控组件有两种方式
2.1、第1种方式
使用步骤 在表单元素中添加ref属性
form onSubmit{this.register}divlabel用户名:/labelinput typetext placeholder请输入用户名 ref{inputthis.nameEleinput}//divdivinput typesubmit value提交/input/div
/form 在通过this.nameEle.value来获取到当前节点的值
register(e){console.log(this.nameEle.value);e.preventDefault();
}
2.2 、第2种方式
使用步骤 调用React.createRef()方法创建一个ref对象
constructor(){super();this.usernameReact.createRef();
} 将创建好的ref对象添加到文本框中 form onSubmit{this.register}divlabel用户名:/labelinput typetext placeholder请输入用户名 ref{this.username}//divdivinput typesubmit value提交/input/div
/form 通过ref对象获取到文本框的值 register(e){console.log(this.username.current.value);e.preventDefault();}