码迷,mamicode.com
首页 > 其他好文 > 详细

react学习之组件(props&state)

时间:2020-09-17 16:10:18      阅读:25      评论:0      收藏:0      [点我收藏+]

标签:render   概念   函数返回   利用   call   变化   mes   vue   timer   

  组件从概念上来看就像JS中的一个函数,它可以接收任意的输入值(称之为props),并返回一个需要在页面上展示的React元素。我们可以将UI切分成几个不同的,独立的,可复用的部分,进行单个部分即单个组件的构建,后面进行整合展示就可。

  一、函数组件和类组件

  组件的名称必须是大写开头,这样是为了在使用时可以和html标签区分开来。函数组件的创建是定义一个首字母大写的函数,这个函数返回jsx,jsx它是依赖React,所以组件内部必须要引入React。在使用组件时,里面写的行内属性都是自定义属性,我们在函数的内部通过props进行接收。组件需要返回一个并且只能返回一个React根元素,所以有多个组件时要用空标签或者是div标签进行包裹。

import React from react;
import ReactDOM from react-dom;

let str = 我是天空里的一片云
//普通函数
function Div(props) {
  // 在组件上使用的行内属性都是自定义属性
  return <h3>我的名字是:{props.name},年龄是:{props.age}</h3>
}
//箭头函数
let H3 = (props) => {
  // 在html标签上使用的行内属性都是react规定的
  return <h3 style={{color:props.style}}>{str}</h3>
}

ReactDOM.render(<>
  <Div name="davina" age={20} />
  <H3  style="ligthblue"></H3>
</>, 
document.querySelector(#root))

  同函数组件一样,类组件首字母也需大写,它继承了React的Component这个类有自己的this和生命周期。如下所示,我们创建了一个Welcome类,它里面必须要有render函数,会默认调用render方法,并且返回一个能被渲染的结果,这个返回结果就是虚拟DOM,即React元素。在return的React元素有多个时,要有标签进行包裹,不然会报错。

  类组件也是先进行属性对象的收集,像下面的<Welcome {...data} />中{ name: ‘davina‘, age: 20 }就会作为Welcome组件的props属性对象进行传入。在传入后,会把属性对象传递给构造函数,并得到类的实例。在props初始化完成后,this.props变量就保存了props属性对象的地址,后面我们在调用render函数时,可以通过this.props访问数据。组件的props一般来源于默认属性或者是由父组件的state内部数据传递而来,基于react是单向数据流,所以在组件内部props是只读的不能修改。虽然可以通过修改父组件的state方式进行修改,但是不建议。它仍旧遵循的是props不可更改这一规则。

import React from react;
import ReactDOM from react-dom;

//Wlecome类继承了React.Component这个类
class Welcome extends React.Component {
  //在class声明的类中有一个规定写了constructor就必须要写super()
  // constructor(props) {
  // super()它相当于是call继承,它其实就是继承的那个类的函数体本身,在这里指的就是React.Component
  // super(props) //将props挂载在this上
  // }
  render() {
    //可以通过this.props调用到属性
    console.log( this.props);
    return <h3>我的名字是:{this.props.name},年龄是:{this.props.age}</h3>
  }
}
let data = { name: davina, age: 20 }
ReactDOM.render(<Welcome {...data} />, document.querySelector(#root))

  二、state

  react中的组件只有两大数据源,一个属性props,二是状态state。上文中我们说了props,下面我们来看一下state。每个组件都有自己独立的内部数据,在类组件中state内部数据是放在构造函数中作为私有属性来定义的。

  当我们要修改state时,因为react不像vue那样对数据进行监听并且在数据变化时刷新视图,而是数据变化通过重新调用render方法,来更新视图。所以我们需要调用render函数。babel提供了一个可以自动调用render函数的APIsetState(),即我们可以利用setState可以触发视图的更新,也就是让render函数执行。换句话说,当我们调用了setState这个函数时,react会更新组件的state,并且重新调用render方法,再把render方法渲染的最新内容显示到页面上。react在更新组件的state时它并不会马上修改state,而是把它放到一个事件队列里面,当数据更数完后才会将新的state提取出来合并到旧的state中,所以只需要传入新的state需要修改的部分就可。随后再进行组件的更新操作。

import React from react;
import ReactDOM from react-dom;
class App extends React.Component {
  constructor(props) {
    super(props)
    //在构造函数中这是唯一可以给this.state赋初始值的地方
    // 当前组件的私有属性
    this.state = {
      name: davina,
      date: new Date().toLocaleTimeString()
    }
  }
  //当组件渲染完成后会触发componentDidMount钩子函数
  componentDidMount() {
    //改变状态的唯一方式就是setState

    this.$timer = setInterval(() => {
      this.setState({ date: new Date().toLocaleTimeString() })
    }, 1000);
  }
  render() {
    //解构赋值
    let { name, date } = this.state;
    return <>
      <h3>我的名字是:{name}</h3>
      <h4> 现在的时间为:{date}</h4>
    </>
  }
}
ReactDOM.render(<App />, document.getElementById(root))

  setState函数它其实是一个异步函数,更新数据时绝大多数情况下是异步操作。但是在原生事件或者是计时器中setTimeout/setInterval这种react无法掌握的API时,会直接去更新state,可以立即得到最新的state它是一个同步的操作。  

  因为在项目中使用setState时绝大多数是异步更新,我们可以使用以下方法强制让react不用异步操作。setState函数式用法即将一个回调函数传入setState方法中或者可以在setState更新后进行的逻辑封装到一个函数中作为第二个参数传给setState即setState(updater,[callback])还可以把需要在setState更新后进行逻辑放在生命周期的hook函数中通过以上的三种方法我们可以实现同步的操作。

import React from react;
import ReactDOM from react-dom;
class App extends React.Component {
  //state的另一种写法,可以不用写constructor
  state = { count: 100, val: 20 }
  add() {
    this.setState(
      { count: this.state.count + 1 }, function () {
        console.log(this.state.count);//这时数据更新完就立即触发,它是一个同步操作
      }
    )
    console.log(this.state.count);//它是一个异步操作,得到的不是立即加1的值,它是旧的state 
  }

  componentDidMount() {
    //同步执行
    this.timer = setInterval(() => {
      this.setState({ val: this.state.val - 1 })
      console.log(this.state.val);
    }, 1000);
  }

  render() {
    let { count, val } = this.state;
    return <>
      <button onClick={this.add.bind(this)}>add</button>
      <h3>count的当前值是:{count}</h3>

      <h4>val的当前值是:{val}</h4>
    </>
  }
}

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

  

 

 

react学习之组件(props&state)

标签:render   概念   函数返回   利用   call   变化   mes   vue   timer   

原文地址:https://www.cnblogs.com/davina123/p/13615162.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!