DEV Community

Jihao Deng
Jihao Deng

Posted on • Edited on

RCT004 React condition and loop

条件渲染与列表渲染

我的笔记里对react.js的学习包含了以下8个内容:

  1. import react.js
  2. JSX
  3. 渲染
  4. Components and props
  5. react 生命周期
  6. 事件处理
  7. 条件渲染 if-else (This note)
  8. 列表渲染 for loop (This note)

对于一个有状态的组件,我们可以根据它的状态来决定该渲染哪些东西。比如一个组件有一个prop是isLogin。它为false时渲染一个前往登录页面的超链接,它为true时渲染用户名以及前往用户个人信息页面的超链接。

组件的状态可以是一个列表,比如通过ajax请求获取了一个list,那么可以通过for循环将它们全部转化成html的标签,然后渲染。这种方式比用jQuery快很多。

需求

一个Navbar,根据用户是否登录来渲染登录的链接或profile链接;
一个ToDoList,用户可以在一个输入框内输入信息,然后点击旁边的按钮将这条信息加入到 to do list 中,然后下面会实时显示list中有那些内容,每一条内容后面都跟了一个remove按钮,点击后这一项就会消失。

获取输入框的内容

输入框内的值应该作为组件的一个状态,也就是说,有一个变量var会实时记录输入框里面的值,需要输入框里面的内容是我们直接访问var,而不是寻找输入框并获得它的值。

在js函数中,我们通过event.target获取到某个html标签对象。

// JSX
<input type="text" value={val} onChange={this.handleInput} placeholder="To do"/>
Enter fullscreen mode Exit fullscreen mode
handleInput = (event) => {
  this.setState({
    value: event.target.value
  })
}
Enter fullscreen mode Exit fullscreen mode

获取html标签的属性

在JSX中,我们可以给html标签赋予任意的属性property,但是如果想在通过event.target获取这些属性,这些属性需要有特定的名称。

标签自定义属性data-xxx='value'

在事件中通过event获取event.target.dataset.xxx

// JSX
<button data-bid={i} onClick={this.handelRemove}>remove</button>
Enter fullscreen mode Exit fullscreen mode
handelRemove = (event) => {
  var kk = event.target.dataset.bid
  console.log(kk)
  var arr = this.state.list;
  arr.splice(kk,1)  // delete the item with index kk
    this.setState({
    list: arr
  })
}
Enter fullscreen mode Exit fullscreen mode

代码

class Navbar extends React.Component {
  state = {
    isLogin: false
  }

  render() {
    if(this.state.isLogin) {
      return (
        <div>
          <a href='login.html'>Please sign in</a>
        </div>
      )
    }
    else {
      return (
        <div>
          <a href='profile.html'>Hello</a>
        </div>
      )
    }
  }
}
class ToDoList extends React.Component {

  state = {
    value: '',
    list: []
  }

  handleAdd = () => {
    const val = this.state.value;
    const list = this.state.list;
    list.push(val);
    this.setState({
      list: list
      // in es6, 'list:list' can be simplified as 'list'
    })
  }

  handleInput = (event) => {
    this.setState({
      value: event.target.value
    })
  }

  handelRemove = (event) => {
    var kk = event.target.dataset.bid
    console.log(kk)
    var arr = this.state.list;
    arr.splice(kk,1)  // delete the item with index kk
    this.setState({
      list: arr
    })
  }

  render() {
    const val = this.state.value;
    const arr = this.state.list;
    const listItem = []
    for(var i = 0; i<arr.length; i++) {
      listItem.push(
        <li key = {i}>
          {arr[i]}
          <button data-bid={i} onClick={this.handelRemove}>remove</button>
        </li>
      )
    }

    return (
      <div>
        <div>
          <input type="text" value={val} onChange={this.handleInput} placeholder="To do"/>
          <button onClick={this.handleAdd}>Add Item</button>
        </div>
        <ul>
          {listItem}
        </ul>
      </div>)
  }
}
ReactDOM.render(
  <Navbar />, document.getElementById('navbar')
)
ReactDOM.render(
  <ToDoList />, document.getElementById('react_container')
)
Enter fullscreen mode Exit fullscreen mode

Inline Conditions in JSX

&& Operator

The JavaScript logical && operator can be handy for conditionally including an element.

function Login(isLogged) {
  return (
    <div>
      <h1>Hello!</h1>
      {!isLogged &&
        <h2>
          Please sign in.
        </h2>
      }
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

? : Operator

Another method for conditionally rendering elements inline is to use the JavaScript conditional operator condition ? trueCode : falseCode.

function Login(isLogged) {
  return (
    <div>
      <h1>Hello!</h1>
      <h3>
      You are <b>{isLogged ? 'currently' : 'not'}</b> logged in.
      </h3>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)