react基础(一)

305 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

大家好呀,我是L同学。最近在学习react,所以在接下来的文章中,我主要总结react的相关知识点。

需求介绍

我们先通过一个案例来介绍react的使用。

现在有个需求,就是点击按钮后,将文本从hello world变为hello react。我们先用原生代码实现,然后用react代码实现,看它们的区别。

image.png

image.png

原生代码实现

<body>
  <h2 class="title"></h2>
  <button class="btn">改变文本</button>

  <script>
    let message = 'hello world'
    const titleEl = document.querySelector('.title')
    // console.log(titleEl);
    titleEl.innerHTML = message

    const btnEl = document.querySelector('.btn')

    btnEl.addEventListener('click', (e) => {
      message = 'hello react'
      titleEl.innerHTML = message
    })
  </script>
</body>

我们可以看到刚开始页面上显示的是hello world。点击按钮后,页面上显示的是hello react。

像这样子的原生代码,我们称之为命令式编程,也就是每做一个操作,都是给计算机(浏览器)一步步的命令。而Vue, React是声明式编程

React实现

使用react开发,必须依赖3个库,分别是react、react-dom、babel。

  • react: 包含了react所必须的核心代码
  • react-dom:react渲染在不同平台所需要的核心代码。针对不同的平台,web端和native端,react会渲染不同的东西。
  • babel:将jsx(JavaScript XML)转换为react代码的工具。babel会将我们编写的jsx语法转换成React.createElement。

所以,我们先通过CDN引入这3个依赖。

  <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>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

我们先把hello world显示在页面上。

<body>
  <div id="app">123</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>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  
  <script type="text/babel">
    let message = 'hello world'
    ReactDOM.render(<h2>{message}</h2>, document.querySelector('#app'))
  </script>
</body>

这里需要注意的是,使用jsx,并且希望script中的jsx代码被babel解析,必须在script标签中添加一个属性type="text/babel"

我们使用的ReactDOM,是react-dom这个库返回给我们的。ReactDOM.render函数接收两个参数。第一个参数是传递需要渲染的内容,可以是html元素,也可以是react组件。第二个参数是将渲染的内容挂载到哪个html元素上。在这个例子中,我们将h2元素挂载到id为app的div元素上。

现在页面上能显示hello world啦。

image.png 接下来,我们需要显示按钮,并且给按钮绑定点击事件。

  <script type="text/babel">
    let message = 'hello world'

    function btnClick() {
      message = 'hello react'
    }
    
    ReactDOM.render(
      (
        <div>
          <h2>{message}</h2>
          <button onClick={btnClick}>改变文本</button>
        </div>
      ), document.querySelector('#app')
    )
  </script>

需要注意的是,jsx使用多个标签时,最外层只能有一个标签。

image.png 我们可以看到按钮已经显示了,也绑定了点击事件,可是点击按钮页面没变化。我们可以打印点击按钮后message的值,此时message已经变成了hello react。页面没有发生变化,是因为数据变化了,我们没有重新调用ReactDOM.render函数。

我们可以将ReactDOM.render函数封装到一个函数中,点击按钮的时候调用这个函数,使得页面重新渲染。

  <script type="text/babel">
    let message = 'hello world'

    function btnClick() {
      message = 'hello react'
      console.log(message);
      render()
    }

    function render() {
      ReactDOM.render(
        (
          <div>
            <h2>{message}</h2>
            <button onClick={btnClick}>改变文本</button>
          </div>
        ), document.querySelector('#app')
      )
    }

    render()
  </script>

此时点击按钮我们可以看到hello world变成了hello react。 image.png 在上面,我们提到ReactDOM.render接收的第一个参数可以是html元素,也可以是组件。那么接下来我们将代码封装到一个组件中。

我们使用类的方式封装组件。定义一个类继承自React.Component。定义的类中实现一个render函数,并且在render函数中返回jsx内容,之后react会帮助我们渲染内容。

  <script type="text/babel">
    class App extends React.Component {
      render() {
        return (
          <div>
            <h2>hello world</h2>
            <button>改变文本</button>
            </div>
          )
      }
    }

    ReactDOM.render(<App/>, document.querySelector('#app'))

  </script>

通过以上代码,我们在页面中看到文本和按钮。

我们把数据定义在当前对象的state中。当数据发生变化时,我们可以调用this.setState来更新数据,并且通知react进行update操作。react在进行update操作时,就会重新调用render函数,并且使用最新数据来渲染界面。

我们在调用btnClick方法时,会发现this指向的是undefined。此时我们需要通过bind方法来绑定当前对象的this。


  <script type="text/babel">
    class App extends React.Component {
      constructor() {
        super()
        // this.message = 'hello world'
        this.state = {
          message: 'hello world'
        }
      }
      render() {
        return (
          <div>
            <h2>{this.state.message}</h2>
            <button onClick={this.btnClick.bind(this)}>改变文本</button>
            </div>
          )
      }

      btnClick() {
        // this.message = 'hello react'
        // this.state.message = 'hello react'
        // console.log(this);
        // console.log(this.state);
        this.setState({
          message: 'hello react'
        })
      }
    }

    ReactDOM.render(<App/>, document.querySelector('#app'))

  </script>