React state理解 浅析React 对state的理解
项哈哈想做前端 人气:0如何定义复杂组件(类组件)与简单组件(函数组件)?
- 是否具有状态(state)
引出问题,什么是状态?
举个例子,今天考试,考砸了,因为我状态不好,是状态影响了我的行为。
组件中的状态,驱动了页面更新,换句话说,组件状态中存着数据,数据的改变,驱动页面的更新。
这里要了解,state状态是谁身上的状态?state状态是组件实例对象身上的状态,不是组件类本身身上的,是由这个类缔造的实例身上的。
(class)组件实例上三大属性之一:state
显示内容
实现一个需求,通过点击页面,炎热/凉爽切换
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>react</title> </head> <body> <div id="test"></div> <!-- 引入核心库 --> <script src="../js/react.development.js"></script> <!-- 扩展库 --> <script src="../js/react-dom.development.js"></script> <!-- 转换jsx转为js --> <script src="../js/babel.min.js"></script> <script type="text/babel"> // 1.创建组件 class Weather extends React.Component { /** * 构造器中能收到什么数据,取决于new的时候,传的是什么数据 * new Weather并不是我们操作的,而是react操作的 */ constructor(props) { // 还没学到props,但得用着,模仿官网写 // 类本身语法 super(props); // 构造函数中this指向构造函数实例对象 // 16.8之前,state是{},16.8及之后,是null this.state = { isHot: true, }; } render() { console.log("this:", this); return <h1>今天天气很炎热</h1>; } } // 2.渲染组件到页面 ReactDOM.render(<Weather />, document.getElementById("test")); </script> </body> </html>
初始化数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>react</title> </head> <body> <div id="test"></div> <!-- 引入核心库 --> <script src="../js/react.development.js"></script> <!-- 扩展库 --> <script src="../js/react-dom.development.js"></script> <!-- 转换jsx转为js --> <script src="../js/babel.min.js"></script> <script type="text/babel"> // 1.创建组件 class Weather extends React.Component { /** * 构造器中能收到什么数据,取决于new的时候,传的是什么数据 * new Weather并不是我们操作的,而是react操作的 */ constructor(props) { // 还没学到props,但得用着,模仿官网写,不然无法执行下去 // 类本身语法 super(props); // 构造函数中this指向构造函数实例对象 // 16.8之前,state是{},16.8及之后,是null this.state = { isHot: true, }; } // state在Weather的实例对象身上 render() { console.log("this:", this); return <h1>今天天气很{this.state.isHot ? "炎热" : "凉爽"}</h1>; } } // 2.渲染组件到页面 ReactDOM.render(<Weather />, document.getElementById("test")); </script> </body> </html>
接下来写点击事件,注意,先做一个错误示范
<script type="text/babel"> // 1.创建组件 class Weather extends React.Component { /** * 构造器中能收到什么数据,取决于new的时候,传的是什么数据 * new Weather并不是我们操作的,而是react操作的 */ constructor(props) { // 还没学到props,但得用着,模仿官网写 // 类本身语法 super(props); // 构造函数中this指向构造函数实例对象 // 16.8之前,state是{},16.8及之后,是null this.state = { isHot: true, }; } // state在Weather的实例对象身上 render() { console.log("this:", this); return ( <h1 onClick={demo()}> 今天天气很{this.state.isHot ? "炎热" : "凉爽"} </h1> ); } } function demo() { console.log("demo被调用"); } // 2.渲染组件到页面 ReactDOM.render(<Weather />, document.getElementById("test")); </script>
我在调用点击事件时,写的是 onClick={demo()}
在控制台会发现,函数被立即执行了
react在new Weather时,通过实例调用了render方法,想拿到return的值,就要执行<h1 onClick={demo()}>今天天气很{this.state.isHot ? “炎热” : “凉爽”}</h1>,执行到onClick赋值语句时,就要将demo()函数调用的返回值交给onClick作为回调,demo()的返回值是undifend,也就是把undifend交给onClick作为回调,**这是错误的做法,是因为在demo后加(),导致函数调用。**等到点击时,就调用了undifend,react处理了这一过程,如果是undifend,就没有多余动作。
常见错误写法
render() { console.log("this:", this); return ( <h1 onClick='demo()'>今天天气很{this.state.isHot ? "炎热" : "凉爽"}</h1> ); }
render() { console.log("this:", this); return ( <h1 onclick='demo'>今天天气很{this.state.isHot ? "炎热" : "凉爽"}</h1> ); }
正确写法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>react</title> </head> <body> <div id="test"></div> <!-- 引入核心库 --> <script src="../js/react.development.js"></script> <!-- 扩展库 --> <script src="../js/react-dom.development.js"></script> <!-- 转换jsx转为js --> <script src="../js/babel.min.js"></script> <script type="text/babel"> // 1.创建组件 class Weather extends React.Component { /** * 构造器中能收到什么数据,取决于new的时候,传的是什么数据 * new Weather并不是我们操作的,而是react操作的 */ constructor(props) { // 还没学到props,但得用着,模仿官网写 // 类本身语法 super(props); // 构造函数中this指向构造函数实例对象 // 16.8之前,state是{},16.8及之后,是null this.state = { isHot: true, }; } // state在Weather的实例对象身上 render() { console.log("this:", this); return ( <h1 onClick={demo}> 今天天气很{this.state.isHot ? "炎热" : "凉爽"} </h1> ); } } function demo() { console.log("demo被调用"); } // 2.渲染组件到页面 ReactDOM.render(<Weather />, document.getElementById("test")); </script> </body> </html>
修改
上文已经将数据渲染到页面中,现在想要修改页面的数据。想要修改数据,首先要拿到state中的isHot,先看一段错误写法:
function demo() { console.log("demo被调用"); // 错误示范 const { isHot } = this.state; console.log("isHot", isHot); }
提示xxx of undefined(reading ‘state'),也就是state of undefined,当xxx为undefined时,undefined.state 就会报这个错误。这里的xxx指的就是this。
来打印一下this
function demo() { // 错误示范 console.log("this", this); const { isHot } = this.state; console.log("isHot", isHot); }
来看一下代码结构和注释
通过打印发现,将自定义函数放到类的外边,数据虽然能够正确显示,但并不能拿到/修改state中的数据。
class Weather extends React.Component { /** * 构造器中能收到什么数据,取决于new的时候,传的是什么数据 * new Weather并不是我们操作的,而是react操作的 */ constructor(props) { // 还没学到props,但得用着,模仿官网写 // 类本身语法 super(props); /** * 构造函数中this指向构造函数实例对象 * 16.8之前,state是{},16.8及之后,是null * state在Weather的实例对象身上 */ this.state = { isHot: true, }; } // 切换天气 demo() { console.log("this", this); const { isHot } = this.state; console.log("isHot", isHot); } // 渲染 render() { console.log("this:", this); return ( <h1 onClick={demo}> 今天天气很{this.state.isHot ? "炎热" : "凉爽"} </h1> ); } }
注意,类不是函数体,不需要写function
加载全部内容