state和props的原理

在网页的一般开发流程中,我们通常会通过 JS 操作 DOM (对应 HTML 的描述产生的树),以引起界面的一些变化响应用户的行为。例如,用户点击某个按钮的时候,JS 会记录一些状态到 JS 变量里边,同时通过 DOM API 操控 DOM 的属性或者行为,进而引起界面一些变化。
当项目越来越大的时候,你的代码会充斥着非常多的界面交互逻辑和程序的各种状态变量,显然这不是一个很好的开发模式,因此就有了 MVVM 的开发模式(例如 React, Vue),提倡把渲染和逻辑分离。
简单来说就是不要再让 JS 直接操控 DOM,JS 只需要管理状态即可,然后再通过一种模板语法来描述状态和界面结构的关系即可。

对于props

props 是 React 组件的输入。它们是从父组件向下传递给子组件的数据。
要有产品的思想,你要实现在屏幕上输出一行字,可以使用react 的通用构造

<div id="root"></div>
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" />;
ReactDOM.render(element, document.getElementById('root'));

1、直接到最后的ReactDOM.render() 函数,传入了前面定义的参数element,里面的值是 <Welcome name="Sara" />
2、element是一个标签(作用就是包裹,相当于div加/div),程序运行到这里时会调用Welcome 组件( 组件名称必须以大写字母开头),组件在最顶上早就编译好,里面包装好了各种标签,样式,等详细信息。
3、element标签启用的时候,同时传入props (也就是{name: 'Sara'}),如果Welcome 组件用到,就会有返回,这里是返回一个标签,标签里的内容是通过props(也就是{name: 'Sara'})传递进去的。
4、返回出来最后会到达ReactDOM.render() 函数对应的document.getElementById('root')会找到public文件夹下index.html的root节点位置,整个react渲染完成。

上面是介绍props,下面举个时钟的例子来承上启下官方链接

<div id="root">				//这里是Html
    <!-- This element's contents will be replaced with your component. -->
</div>
function tick() {			//这里是JS
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>	//根据本地时间把 Date 对象的时间部分转换为字符串,就是输出时间而已
    </div>
  );
  ReactDOM.render(    element,    document.getElementById('root')  );
}

setInterval(tick, 1000);		//这是一个每秒钟运行的永动机

在实践中,大多数 React 应用只会调用一次 ReactDOM.render()。
这里是直接每秒钟调用tick函数,函数里有ReactDOM.render(),所以也就是每秒都调用 ReactDOM.render()。
每次调用Tick函数,都会自动把新日期给常量element赋值更新,这样的话简单粗暴。

对于state

下面是最终代码,也和上面一样,不过是在组件里实现更新实时时间。

<div id="root">
    <!-- This element's contents will be replaced with your component. -->
</div>
class Clock extends React.Component {			//这里定义了一个组件,包括继承谁(设置默认值),生命周期函数,渲染返回。
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  
//componentDidMount() 方法会在组件已经被渲染到 DOM 中后运行,所以,最好在这里设置计时器
  componentDidMount() {	    //永动机启动,每秒去调用tick()更新时间,这个等于号把计时器的 ID 保存在 this 之中(this.timerID)
    this.timerID = setInterval(      () => this.tick(),      1000    );
  }

  componentWillUnmount() {		//组件在DOM渲染以后启动上面的挂载函数,卸载的时候就要把timerID也清除掉
    clearInterval(this.timerID);
  }

  tick() {							//react发现state改变,就会自动重新render渲染
    this.setState({      date: new Date()    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
  
}
ReactDOM.render(  <Clock />,  document.getElementById('root'));

每次组件更新时 render 方法都会被调用,但只要在相同的 DOM 节点中渲染 ,就仅有一个 Clock 组件的 class 实例被创建使用。这就使得我们可以使用如 state 或生命周期方法等很多其他特性。
下面是程序运行流程,要注意的是,渲染过程它是自动进行的。
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值