Ver Fonte

类组件与state

daxia há 1 ano atrás
pai
commit
c31c04b09d

+ 75 - 0
20_React.js_VIP22/React.js快速进坑.md

@@ -343,6 +343,81 @@ props 是 组件与外部数据交互的接口。同时还是响应式,即当p
 
 ### 5.2 state
 
+state 是 组件内部自己拥有的状态数据。不同于 props ,props 是 只读的,但是 state 是可以修改的。同时state变化后,组件会重新渲染。
+
+如果想要组件内部拥有状态state,在不使用hooks时,必须通过es6中的类来定义组件,这样在类组件渲染时,会创建组件实例。通过组件实例的state属性 去存储 所有内部的状态(state类型为object对象)。
+
+其中,类名就是组件名,也遵循PascalCase命名法。
+
+```jsx
+// 定义类Greeting 继承自 React.Component
+// 此时,即为Greeting 组件
+class Greeting extends React.Component {
+  // 定义render实例方法
+  render() {
+    return (
+      <div>
+        <h3>你好,兄弟!</h3>
+      </div>
+    );
+  }
+}
+```
+
+上述代码要求:
+
+1. 类必须继承`React.Component`才会是组件
+2. 必须含有render实例方法,用来返回组件最终渲染效果UI
+
+接下来,看一个计数器案例:
+
+```jsx
+class Counter extends React.Component {
+// 添加状态
+  state = {
+    name: '计数器',
+    count: 0, // 定义一个计数的状态值
+  };
+  reduceOne() {
+    // console.log(this);
+    // 类Vue,如果直接修改state可以吗?
+    // this.state.count--;// wrong
+    // 正确做法
+  	this.setState({
+    	count: this.state.count - 1,
+  	});
+  }
+  addOne = () => {
+    // console.log(this);
+    this.setState({
+      count: this.state.count + 1,
+    });
+	};
+
+  render() {
+    // 1 在类组件中 通过this先拿到组件实例,然后通过访问state属性得到所有的状态。
+    return (
+      <div>
+        <h3>{this.state.name}</h3>
+        <p>当前值:{this.state.count}</p>
+        <p>
+          <button onClick={this.reduceOne.bind(this)}>-</button>
+          <button onClick={this.addOne}>+</button>
+        </p>
+      </div>
+    );
+  }
+}
+```
+
+上面代码小结:
+
+1. 获取状态state:通过 `this`先拿到组件实例;再访问state属性获取到所有的状态。
+2. 修改状态state:必须通过组件实例的`setState方法`才可以。
+3. `setState(newState | (prevState, props) => newState)`该方法在修改状态时,会将旧的state与setState传入新的state合并后产生的新状态对象 替换 旧状态对象的方式来实现响应式的。因此在调用setState时,要么直接传入一个新的状态对象,或者传入一个函数,该回调函数返回一个新state对象。
+
+
+
 ### 5.3 组件生命周期
 
 ## 6. 条件渲染

+ 0 - 0
20_React.js_VIP22/day-2/code/2.props.html → 20_React.js_VIP22/day-2/code/2.props copy.html


+ 74 - 0
20_React.js_VIP22/day-2/code/3.state.html

@@ -0,0 +1,74 @@
+<!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>Document</title>
+    <script src="../react.development.js"></script>
+    <script src="../react-dom.development.js"></script>
+    <script src="../babel.min.js"></script>
+  </head>
+  <body>
+    <div id="root"></div>
+    <script type="text/babel">
+      class Greeting extends React.Component {
+        render() {
+          return (
+            <div>
+              <h3>你好,兄弟!</h3>
+            </div>
+          );
+        }
+      }
+
+      class Counter extends React.Component {
+        // 添加状态
+        // 写法-1
+        state = {
+          name: '计数器',
+          count: 0, // 定义一个计数的状态值
+        };
+        // 写法-2
+        // constructor(props) {
+        //   super(props); // 在继承关系中,下面代码要使用this 的话 必须先调用super父类的构造器才可以
+        //   this.state = {};
+        // }
+        // 像vue那样 定义实例方法来作为事件监听器
+        // 2 修改状态:一定要保证其响应式,那么只能通过 组件实例的setState方法
+        reduceOne() {
+          // console.log(this);
+          // 类Vue,如果直接修改state可以吗?
+          // this.state.count--;// wrong
+          // 正确做法
+          this.setState({
+            count: this.state.count - 1,
+          });
+        }
+        addOne = () => {
+          // console.log(this);
+          this.setState({
+            count: this.state.count + 1,
+          });
+        };
+
+        render() {
+          // 1 在类组件中 通过this先拿到组件实例,然后通过访问state属性得到所有的状态。
+          return (
+            <div>
+              <h3>{this.state.name}</h3>
+              <p>当前值:{this.state.count}</p>
+              <p>
+                <button onClick={this.reduceOne.bind(this)}>-</button>
+                <button onClick={this.addOne}>+</button>
+              </p>
+            </div>
+          );
+        }
+      }
+
+      let element = <Counter />; // 将组件 => jsx(React元素)
+      ReactDOM.createRoot(document.querySelector('#root')).render(element);
+    </script>
+  </body>
+</html>