可以温习下前置知识
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>类式组件title>
- head>
- <body>
- <div id="app">div>
- <script src="js/react.development.js">script>
- <script src="js/react-dom.development.js">script>
- <script src="js/babel.min.js">script>
-
- <script type="text/babel"> // 此处一定要写babel
- // 创建函数式组件 首字母要大写
- class MyComponent extends React.Component{
- render(){
- // render是放在哪里的 MyComponent 的原型对象上。供实例使用
- console.log('render中的this:',this) // render里的this是 MYComponent的实例对象 === MYComponent组件实例对象
- return <h2>我是类定义的组件-适用于复杂组件的定义h2>
- }
- }
-
-
-
- // 渲染虚拟DOM到页面 函数定义的组件要写 闭合标签
- ReactDOM.render(<MyComponent/>,document.querySelector('#app'))
-
- script>
-
-
-
-
- body>
- html>
定义类式组件 ReactDOM.render(
1.React解析组件标签,找到了MyComponent组件
2.发现组件是使用类定义的。随后new出来该类的实例,并通过该实例调用render方法
3.将render 返回的虚拟DOM 转化为真实DOM 随后呈现在页面中
组件的状态(数据) 直接定义到class 中 通过this.setState 方法修改 修改后自动render 更新页面
- class Weather extends React.Component{
- //初始化状态
- state = {isHot:false,wind:'微风'}
-
- render(){
- const {isHot,wind} = this.state
- return <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '凉爽'},{wind}h1>
- }
-
- //自定义方法————要用赋值语句的形式+箭头函数
- changeWeather = ()=>{
- const isHot = this.state.isHot
- this.setState({isHot:!isHot})
- }
- }
- //2.渲染组件到页面
- ReactDOM.render(<Weather/>,document.getElementById('test'))
组件内的回调方法 都是用箭头函数 因为箭头函数this 指向上下文 ==》组件实例对象 可以正确的调用到各种方法 还可以获取到想要的 this.ref
改变state的两种方式
- export default class Extension1 extends Component {
- state = {
- num:199
- }
-
- changeObj = () =>{
- this.setState({
- num:this.state.num - 8
- },() =>{
- console.log(this.state.num);
- })
- }
- // 第二个参数可以传入一个函数 在render之后才执行
-
- changeFun = () =>{
- this.setState( (state,props) => ({num:props.add * state.num}))
- }
-
-
-
- render() {
- const {num} = this.state
- return (
- <div>
- <h2>当前组件的数据是{num}h2>
- <button onClick={this.changeObj}>点击改变数据(对象方式)button>
- <button onClick={this.changeFun}>点击改变数据(函数方式)button>
- div>
- )
- }
- }
(1). setState(stateChange, [callback])------对象式的setState
1.stateChange为状态改变对象(该对象可以体现出状态的更改)
2.callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用
(2). setState(updater, [callback])------函数式的setState
1.updater为返回stateChange对象的函数。
2.updater可以接收到state和props。
4.callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用。
总结:
1.对象式的setState是函数式的setState的简写方式(语法糖)
2.使用原则:
(1).如果新状态不依赖于原状态 ===> 使用对象方式
(2).如果新状态依赖于原状态 ===> 使用函数方式
(3).如果需要在setState()执行后获取最新的状态数据,
要在第二个callback函数中读取
组件内部接收外部传来的数据 还可以进行 类型限制 默认值指定
基本用法
- //创建组件
- class Person extends React.Component{
- render(){
- // console.log(this);
- const {name,age,sex} = this.props
- return (
- <ul>
- <li>姓名:{name}li>
- <li>性别:{sex}li>
- <li>年龄:{age+1}li>
- ul>
- )
- }
- }
- //渲染组件到页面
- ReactDOM.render(<Person name="jerry" age={19} sex="男"/>,document.getElementById('test1'))
- ReactDOM.render(<Person name="tom" age={18} sex="女"/>,document.getElementById('test2'))
-
- const p = {name:'老刘',age:18,sex:'女'}
- // console.log('@',...p);
- // ReactDOM.render(
,document.getElementById('test3')) - ReactDOM.render(<Person {...p}/>,document.getElementById('test3'))
对类型和默认值进行限制
需要引入专门支持的库
//对标签属性进行类型、必要性的限制
Person.propTypes = {
name:PropTypes.string.isRequired, //限制name必传,且为字符串
sex:PropTypes.string,//限制sex为字符串
age:PropTypes.number,//限制age为数值
speak:PropTypes.func,//限制speak为函数
}
//指定默认标签属性值
Person.defaultProps = {
sex:'男',//sex默认值为男
age:18 //age默认值为18
}
}>
-
- class C extends PureComponent {
-
- render(){
- const ccc = 123
- return (
- <div className='child'>
- <p>以下是预留的插槽p>
- {this.props.render(ccc)}
- div>
- )
- }
- }
-
- class D extends PureComponent {
-
- render(){
- return (
- <div style={{background:'#f35'}}>
- <h3>我是D组件h3>
- {this.props.ccc}
- div>
- )
- }
- }
字符串方式:
- //创建组件
- class Demo extends React.Component{
- //展示左侧输入框的数据
- showData = ()=>{
- const {input1} = this.refs
- alert(input1.value)
- }
- //展示右侧输入框的数据
- showData2 = ()=>{
- const {input2} = this.refs
- alert(input2.value)
- }
- render(){
- return(
- <div>
- <input ref="input1" type="text" placeholder="点击按钮提示数据"/>
- <button onClick={this.showData}>点我提示左侧的数据button>
- <input ref="input2" onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>
- div>
- )
- }
- }
- //渲染组件到页面
- ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
回调函数形式的ref
c 就是 currentNode 返回一个回调函数 currentNode(当前节点) 赋值给 this.xxx
再在一些回调函数中 使用 this.xxx.value
ref回调形式中 次数的问题 在更新中(改变状态重新render)会执行两次 第一次参数传入为null 为了清空 第二次才是 currentNode 通过将ref的回调函数 定义成class 绑定函数的方式 可以避免上述问题但大多数情况下 它是无关紧要的
saveinput = (e) => {
this.inputvalue = e
}
handleClick1 = () => {
console.log(this.inputvalue.value);
};
- //创建组件
- class Demo extends React.Component{
- //展示左侧输入框的数据
- showData = ()=>{
- const {input1} = this
- alert(input1.value)
- }
- //展示右侧输入框的数据
- showData2 = ()=>{
- const {input2} = this
- alert(input2.value)
- }
- render(){
- return(
- <div>
- <input ref={c => this.input1 = c } type="text" placeholder="点击按钮提示数据"/>
- <button onClick={this.showData}>点我提示左侧的数据button>
- <input onBlur={this.showData2} ref={c => this.input2 = c } type="text" placeholder="失去焦点提示数据"/>
- div>
- )
- }
- }
- //渲染组件到页面
- ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
- //创建组件
- class Demo extends React.Component{
- /*
- React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的
- */
- myRef = React.createRef()
- myRef2 = React.createRef()
- //展示左侧输入框的数据
- showData = ()=>{
- alert(this.myRef.current.value);
- }
- //展示右侧输入框的数据
- showData2 = ()=>{
- alert(this.myRef2.current.value);
- }
- render(){
- return(
- <div>
- <input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>
- <button onClick={this.showData}>点我提示左侧的数据button>
- <input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="失去焦点提示数据"/>
- div>
- )
- }
- }
- //渲染组件到页面
- ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
- //1.创建函数式组件
- function MyComponent(){
- console.log(this); //此处的this是undefined,因为babel编译后开启了严格模式
- return <h2>我是用函数定义的组件(适用于【简单组件】的定义)h2>
- }
- //2.渲染组件到页面
- ReactDOM.render(<MyComponent/>,document.getElementById('test'))
执行了ReactDOM.render(
1.React解析组件标签,找到了MyComponent组件。
2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面中。
因为函数式组件没有自己的this 所以它不能使用 state 和 refs
可以正常接收props
- function Person (props){
- const {name,age,sex} = props
- return (
- <ul>
- <li>姓名:{name}li>
- <li>性别:{sex}li>
- <li>年龄:{age}li>
- ul>
- )
- }
- Person.propTypes = {
- name:PropTypes.string.isRequired, //限制name必传,且为字符串
- sex:PropTypes.string,//限制sex为字符串
- age:PropTypes.number,//限制age为数值
- }
-
- //指定默认标签属性值
- Person.defaultProps = {
- sex:'男',//sex默认值为男
- age:18 //age默认值为18
- }
- //渲染组件到页面
- ReactDOM.render(<Person name="jerry"/>,document.getElementById('test1'))
(1). State Hook: React.useState()
(2). Effect Hook: React.useEffect()
(3). Ref Hook: React.useRef()