React笔记 #04# 对state的理解

react

饮水思源:https://www.bilibili.com/video/BV1wy4y1D7JT?p=12

一句话:状态驱动页面,状态改变,页面改变。

简单组件

被传入的数据可在组件中通过 this.props 在 render() 访问。

  <script type="text/babel">

let 容器 = document.querySelector("#test");

class 这是一个简单组件 extends React.Component {

render() {

console.log(this)

return <h2>我是{this.props.name}</h2>

}

}

ReactDOM.render(<这是一个简单组件 name={"火车王"} />, 容器);

</script>

有状态组件

直接抄官网:除了使用外部数据(通过 this.props 访问)以外,组件还可以维护其内部的状态数据(通过 this.state 访问)。当组件的状态数据改变时,组件会再次调用 render() 方法重新渲染对应的标记。

解决类中this指向问题:https://www.bilibili.com/video/BV1wy4y1D7JT?p=16

效果演示(点击文字改变):

状态不能直接更改,要借助内部API更改(严重注意!),且setState是合并不是替换。错误示例:

  <script type="text/babel">

let 容器 = document.querySelector("#test");

let that;

class 这是一个有状态的组件 extends React.Component {

constructor(props) {

super(props) // 为了接属性

this.state = {

name: "火车王",

}

that = this;

}

render() {

console.log(this)

return <h2 onClick={changeName}>我是{this.state.name}</h2>

}

}

ReactDOM.render(<这是一个有状态的组件 />, 容器);

function changeName() {

console.log(that)

console.log("函数被" + that.state.name + "触发");

if (that.state.name == "火车王") {

that.state.name = "火车王的儿子"

} else {

that.state.name = "火车王"

}

}

</script>

无效代码

采用setState。写法一:

    let 容器 = document.querySelector("#test");

let that;

class 这是一个有状态的组件 extends React.Component {

constructor(props) {

super(props) // 为了接属性

this.state = {

name: "火车王",

}

that = this;

}

render() {

return <h2 onClick={changeName}>我是{this.state.name}</h2>

}

}

ReactDOM.render(<这是一个有状态的组件 />, 容器);

function changeName() {

let str;

if (that.state.name == "火车王") {

str = "火车王的儿子"

} else {

str = "火车王"

}

that.setState({name: str});

}

写法二:

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8" />

<title>Add React in One Minute</title>

</head>

<body>

<div ></div>

<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>

<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>

<!-- Load Babel -->

<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

<script type="text/babel">

let 容器 = document.querySelector("#test");

class 这是一个有状态的组件 extends React.Component {

constructor(props) {

super(props) // 为了接属性

this.state = {

name: "火车王",

}

this.changeName = changeName.bind(this);

}

render() {

return <h2 onClick={this.changeName}>我是{this.state.name}</h2>

}

}

ReactDOM.render(<这是一个有状态的组件 />, 容器);

function changeName() {

let str;

if (this.state.name == "火车王") {

str = "火车王的儿子"

} else {

str = "火车王"

}

this.setState({name: str});

}

</script>

</body>

</html>

把changeName挂在原型上也行:

    let 容器 = document.querySelector("#test");

class 这是一个有状态的组件 extends React.Component {

constructor(props) {

super(props) // 为了接属性

this.state = {

name: "火车王",

}

this.changeName = this.changeName.bind(this);

}

render() {

console.log(this);

return <h2 onClick={this.changeName}>我是{this.state.name}</h2>

}

changeName() {

let str;

if (this.state.name == "火车王") {

str = "火车王的儿子"

} else {

str = "火车王"

}

this.setState({name: str});

}

}

ReactDOM.render(<这是一个有状态的组件 />, 容器);

必须注意,this.changeName = this.changeName.bind(this);是必要的,因为onClick时,changeName是作为回调函数调用的,而不是通过对象实例调用,也就是说,他的this的指向是有问题的。

简写形式。在class中直接写赋值语句是直接挂在对象上而不是原型上的,必须用箭头函数而不可以用function,箭头函数没有自己的this:

  <script type="text/babel">

let 容器 = document.querySelector("#test");

class 这是一个有状态的组件 extends React.Component {

state = { // 在对象上

name: "火车王",

}

changeName = () => { // 自定义方法,在对象上,不在对象原型上

console.log(this);

let str;

if (this.state.name == "火车王") {

str = "火车王的儿子"

} else {

str = "火车王"

}

this.setState({name: str});

}

render() {

return <h2 onClick={this.changeName}>我是{this.state.name}</h2>

}

}

ReactDOM.render(<这是一个有状态的组件 />, 容器);

</script>

小结

强烈注意,render方法中的this为组件实例对象

组件自定义方法中的this在作为回调函数调用时,为undefined,解决办法是:

通过bind()强制绑定this;或者,在class中写箭头函数,因为箭头函数本身不带this

以上是 React笔记 #04# 对state的理解 的全部内容, 来源链接: utcz.com/z/382645.html

回到顶部