React框架入门学习(二)组件学习(state PK props)

组件就是页面编排过程中很重要的组成部件,就像搭积木一样,把组件一块一块地拼接起来,可以把这块拼上去,也可以把那块拆下来。

具体知识可以参照React官方手册。

 React官方中文文档地址:    https://doc.react-china.org/

state

一个组件的显示形态是可以由它数据状态和配置参数决定的。一个组件可以拥有自己的状态,就像一个按钮,可以有“同

意”和“不同意”状态,并且可以在这两种状态之间进行切换。

React.js 的 state 就是用来存储这种可变化的状态的。

setState 方法由父类 Component 所提供。当我们调用这个函数的时候,React.js 会更新组件的状态 state ,并且重新调

用 render 方法,然后再把 render 方法所渲染的最新的内容显示到页面上

注意,当我们要改变组件的状态的时候,不能直接用 this.state = xxx 这种方式来修改,如果这样做 React.js 就没办法知道

你修改了组件的状态,它也就没有办法更新页面。所以,一定要使用 React.js 提供的 setState 方法,它接受一个对象或者

函数作为参数

State中的属性只能在组件内部声明和使用。

setState 接受函数参数

这里还有要注意的是,当你调用 setState 的时候,React.js 并不会马上修改 state。而是把这个对象放到一个更新队列里面,稍后才会从队列当中把新的状态提取出来合并到 state 当中,然后再触发组件更新。这一点要好好注意。可以体会一下下面的代码:

...
  handleClickOnLikeButton () {
    console.log(this.state.isLiked)
    this.setState({
      isLiked: !this.state.isLiked
    })
    console.log(this.state.isLiked)
  }
...

你会发现两次打印的都是 false,即使我们中间已经 setState 过一次了。这并不是什么 bug,只是 React.js 的 setState 把你的传进来的状态缓存起来,稍后才会帮你更新到 state 上,所以你获取到的还是原来的 isLiked

所以如果你想在 setState 之后使用新的 state 来做后续运算就做不到了,例如:

...
  handleClickOnLikeButton () {
    this.setState({ count: 0 }) // => this.state.count 还是 undefined
    this.setState({ count: this.state.count + 1}) // => undefined + 1 = NaN
    this.setState({ count: this.state.count + 2}) // => NaN + 2 = NaN
  }
...

上面的代码的运行结果并不能达到我们的预期,我们希望 count 运行结果是 3 ,可是最后得到的是 NaN。但是这种后续操作依赖前一个 setState 的结果的情况并不罕见。

这里就自然地引出了 setState 的第二种使用方式,可以接受一个函数作为参数。React.js 会把上一个 setState 的结果传入这个函数,你就可以使用该结果进行运算、操作,然后返回一个对象作为更新 state 的对象:

...
  handleClickOnLikeButton () {
    this.setState((prevState) => {
      return { count: 0 }
    })
    this.setState((prevState) => {
      return { count: prevState.count + 1 } // 上一个 setState 的返回是 count 为 0,当前返回 1
    })
    this.setState((prevState) => {
      return { count: prevState.count + 2 } // 上一个 setState 的返回是 count 为 1,当前返回 3
    })
    // 最后的结果是 this.state.count 为 3
  }
...

这样就可以达到上述的利用上一次 setState 结果进行运算的效果。

setState 合并

上面我们进行了三次 setState,但是实际上组件只会重新渲染一次,而不是三次;这是因为在 React.js 内部会把 JavaScript 事件循环中的消息队列的同一个消息中的 setState 都进行合并以后再重新渲染组件。

深层的原理并不需要过多纠结,只需要记住的是:在使用 React.js 的时候,并不需要担心多次进行 setState 会带来性能问题。


       而Props是上一层的组件传递给下一层的参数,比如:有两个组件,“main”和“view”,main是上一层的组件,view被包含在main当中,是main的子组件,那么main组件就可以把参数通过Props传递给view组件。这一过程是不可逆的,无法从view传回到main,也就涉及到了React框架的单向数据流的特性。如下图所示:

(这里摘自https://blog.csdn.net/daxiazouyizou/article/details/79754021

    


  ndex.js代码如下:前两个是react生成和render需要的包,import App from './App';是导入自己写的组件:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App/>, document.getElementById('root'));

在已经生成的my-new-app中,APP.js代码如下,这里采用继承React.Component组件的办法(类的方式)新建组件:

import React from 'react';

class App extends React.Component {
	constructor(props) { //构造函数
		super(props);
		this.state = {
			text : 'This is TEXT!'
		}
	}
	
	render(){
		return(<div>{this.state.text}</div>)
	}
}
export default App;

下方的“export default App;”作用是将App组件发布出去,也就是说其他文件可以通过App这个名称从该文件中获取App组件。

保存后,可以看到:


下面来介绍Props的用法,既然要用到Props,就需要再创建一个组件内容,其构造方式与App组件相似,只是在render函数中return的标签内输入{ this.props.text },意思就是获取并显示上一个组件传到这个组件的数据中名称为“text”的属性值。如下所示:

import React from 'react';

class PropsTest extends React.Component {
	constructor(props) { //构造函数
		super(props);
		this.state = {
		}
	}
	render(){
		return(<div>{this.props.text}</div>)
	}
}
export default PropsTest;

对APP.js进行更改:

import React from 'react';
import PropsTest from './propsTest';

class App extends React.Component {
	constructor(props) { //构造函数
		super(props);
		this.state = {
			text : 'This is TEXT!'
		}
	}

	render(){
		let text = this.state.text;
		return(<PropsTest text={text} />)
	}
}
export default App;

    在render函数里,通过let创建一个变量text,获取state中的text属性的值。

    然后再return里面输入<PropsTest/> 标签,并在其中添加语句 text={ text },意思就是将上面let的text变量传输到PropsTest组件中。

    保存两个文件,就能在网页窗口中看到和之前一样的内容,但之前是由App组件显示其State里的属性,而现在是由PropsTest组件获取App组件传来的Props中的text属性,然后将其显示出来。一个来自State,一个来自Props。

接下来完成的是react路由的选择   https://blog.csdn.net/weixin_30363263/article/details/80992288


猜你喜欢

转载自blog.csdn.net/weixin_30363263/article/details/80976163