react基础(三)

136 阅读4分钟

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

前言

大家好呀,我是L同学。在上篇文章中,我们学习了jsx的基本语法以及使用react基础(二)—— jsx使用。并且,我们讲到了如何在react中绑定事件。接下来在这篇文章中,我们会学习如何在事件中传递参数,进行条件渲染,列表渲染等内容。

jsx绑定事件-传递参数

获取event对象

在event对象中包含了很多信息。有时候我们就需要拿到event对象来做一些事情,比如阻止默认行为等。

在原生中,我们可以通过这种方式拿到event对象。

<body>
  <button class="btn">按钮</button>
  <script>
    document.querySelector('.btn').addEventListener('click', e => {
      console.log(e);
    })
  </script>
</body>

点击按钮,我们可以拿到event对象,里面包含了很多信息。

image.png 那么在react中如何拿到event对象呢?

我们可以直接在函数中拿到event对象。

<body>
  <div id="app"></div>
  <script src="../react/react.development.js"></script>
  <script src="../react/react-dom.development.js"></script>
  <script src="../react/babel.min.js"></script>

  <script type="text/babel">
    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          names: ['abc', 'cba', 'nba']
        }
        
        this.btnClick = this.btnClick.bind(this)
      }
      render() {
        return (
          <div>
            <button onClick={this.btnClick}>按钮</button>
            <ul>
              {
                this.state.names.map(item => <li>{item}</li>)
              }
            </ul>
          </div>
        )
      }

      btnClick(event) {
        console.log('按钮发生了点击', event);
      }
    }

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

  </script>
</body>

我们可以看到点击了按钮,能够获取到事件对象。

image.png

获取其他参数

除了event对象,我还想获取到其他参数呢,这个该怎么做呢?在上述例子中,点击每个li标签,打印出它的index。

绑定事件时,要注意this指向。在上篇文章中,我们介绍了处理this问题的几种方法react基础(二)—— jsx使用

有更多参数时,我们最好的方法就是传入一个箭头函数,主动执行的事件函数,并且传入相关的其他参数。

 <script type="text/babel">
    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          names: ['abc', 'cba', 'nba']
        }
      }
      render() {
        return (
          <div>
            <ul>
              {
                this.state.names.map((item, index, arr) => {
                  return (
                    <li className="item"
                      title="li"
                      onClick={(e) => {this.liClick(item, index, e)}}
                    >{item}</li>
                  )
                })
              }
            </ul>
          </div>
        )
      }

      liClick(item, index, event) {
        console.log('li发生了点击', item, index, event);
      }
    }

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

  </script>

我们可以看到点击各个li标签,我们能拿到对应li的内容、index和event对象。

image.png

react条件渲染

在很多情况下,我们经常需要根据某些条件判断是否渲染内容。在react中,所有的条件判断和普通的javascript代码一致。

方法一: 条件判断语句

条件判断语句适合逻辑较多的情况。

现在有个需求,根据isLogin状态来显示不同的内容,isLogin为true页面上显示欢迎回来,为false显示请先登录。

  <script type="text/babel">
    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          isLogin: true
        }
      }

      render() {
        const { isLogin } = this.state
        // 方法一:通过if条件判断:适合逻辑代码非常多的情况
        let welcome = null
        if (isLogin) {
          welcome = <h2>欢迎回来!</h2>
        }else {
          welcome = <h2>请先登录!</h2>
        }
        return (
          <div>
          
            {welcome}
          </div>
        )
      }
    }

    ReactDOM.render(<App />, document.getElementById('app'))
  </script>
</body>

image.png

方法二: 三元运算符

三元运算符适合逻辑比较简单的情况。

在上个需求的基础上,增加一个按钮,如果是登陆的情况下按钮文本显示退出,未登录的情况下按钮文本显示登陆。同时点击按钮改变welcome中的内容。

image.png

image.png

我们通过三元运算符来进行判断。

    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          isLogin: true
        }
      }

      render() {
        const { isLogin } = this.state
        let welcome = null
        // 方法一:通过if条件判断:适合逻辑代码非常多的情况
        if (isLogin) {
          welcome = <h2>欢迎回来!</h2>
        } else {
          welcome = <h2>请先登录</h2>
        }
        return (
          <div>
            {welcome}
            {/* 方法二:三元运算符 */}
            <button onClick={e => this.loginClick(e)}>{isLogin ? '退出' : '登录'}</button>
          </div>
        )
      }

      loginClick(e) {
        this.setState({
          isLogin: !this.state.isLogin
        })
      }
    }

方法三 与运算符&&

逻辑与&&:一个条件不成立,后面所有的条件都不会进行判断。

逻辑与&&适合如果条件成立,渲染某一个组件;如果条件不成立,什么内容也不渲染。因为布尔值fasle在{}中不显示。

    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          isLogin: true
        }
      }

      render() {
        const { isLogin } = this.state
        let welcome = null
        // 方法一:通过if条件判断:适合逻辑代码非常多的情况
        if (isLogin) {
          welcome = <h2>欢迎回来!</h2>
        } else {
          welcome = <h2>请先登录</h2>
        }
        return (
          <div>
            {welcome}
            {/* 方法二:三元运算符 */}
            <button onClick={e => this.loginClick(e)}>{isLogin ? '退出' : '登录'}</button>

            {/* 单标签后必须加/ */}
            <hr />

            {/* null在jsx中不显示内容 */}
            <h2>{isLogin ? '你好呀,Q同学' : null}</h2>
            {/* 方法三:逻辑与&&  */}
            <h2>{isLogin && '你好呀,Q同学'}</h2>
            { isLogin && <h2>你好呀,Q同学</h2> }
            </div>
        )
      }

            loginClick(e) {
              this.setState({
                isLogin: !this.state.isLogin
              })
            }
    }

image.png

image.png

模拟v-show效果

在vue中可以通过v-show来控制元素的显示与隐藏,主要是控制display属性是否为none。现在我们通过react来模拟下。

  <script type="text/babel">
    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          isLogin: true
        }
      }

      render() {
        const { isLogin } = this.state
        const titleDisplayValue = isLogin ? 'block' : 'none'
        return (
          <div>
            <button onClick={e => this.loginClick()}>{isLogin ? '退出' : '登录'}</button>
            <h2 style={{ display: titleDisplayValue }}>你好呀,Q同学</h2>
          </div>
        )
      }

      loginClick() {
        this.setState({
          isLogin: !this.state.isLogin
        })
      }
    }

    ReactDOM.render(<App />, document.getElementById('app'))
  </script>

image.png

image.png

react列表渲染

我们想要把数组中的内容渲染到页面上,在vue中我们可以使用v-for指令。那么在react中我们可以使用javascript中的map方法将数组遍历出来。另外在遍历之前,我们还可能需要对数组进行处理,比如对数组进行过滤,截取等操作。我们可以使用filter方法过滤数据,使用slice方法截取部分内容。

  <script type="text/babel">
    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          names: ['小明', '小红', '小王', '小何'],
          numbers: [1, 2, 3, 4, 5, 6, 7]
        }
      }
      render() {
        return (
          <div>
            <h2>名字列表</h2>
            <ul>
              {
                this.state.names.map(item => {
                  return <li>{item}</li>
                })
              }
            </ul>

            <h2>数字列表展示大于5的数字(过滤)</h2>
            <ul>
              {
                this.state.numbers.filter(item => {
                  return item > 5
                }).map(item => {
                  return <li>{item}</li>
                })
              }
            </ul>

            <h2>数字列表展示大于5的数字(过滤)</h2>
            <ul>
              {
                this.state.numbers.filter(item => item > 5).map(item => <li>{item}</li>)
              }
            </ul>

            <h2>数字列表截取前4个数字</h2>
            <ul>
            {
              this.state.numbers.slice(0, 4).map(item => {
                return <li>{item}</li>
              })
            }  
            </ul>
          </div>
        )
      }

    }

    ReactDOM.render(<App />, document.getElementById('app'))
  </script>