React事件傳參深度理解

天藍藍tao發表於2018-12-26

1.第一種方式,用一個箭頭函式包在外面,因為這個箭頭函式只有點選的時候才會執行,只有當這個箭頭函式執行的時候,裡面呼叫的方法才會執行

// 子元件負責傳遞引數
render() {
    return (
        <ol>
          {
            this.props.todos.map(item => {
              return (
                <li key={item.id}>
                  <span>{item.title}</span>
                  <button onClick={() => {this.props.handleDelectItem(item.id)}}>刪除</button>
                </li>
              )
            })
          }
        </ol>
    )
  }
複製程式碼
// 父元件負責接受傳過來的引數,進行處理
handleDelectItem = (id) => {
    const todos = this.state.todos.filter(item => item.id !== id)
    this.setState({
      todos
    })
  }
  
render() {
    return (
      <div>
          <ToDoList todos={this.state.todos} handleDelectItem={this.handleDelectItem}/>
      </div>
    );
  }
複製程式碼

注意:

如果在子元件中不用箭頭函式將呼叫的方法包起來,該方法會立即執行(就相當於立即執行函式)

render() {
    return (
        <ol>
          {
            this.props.todos.map(item => {
              return (
                <li key={item.id}>
                  <span>{item.title}</span>
                  <button onClick={ this.props.handleDelectItem(item.id)}>刪除</button>
                </li>
              )
            })
          }
        </ol>
    )
  }
複製程式碼

2.第二種方式,使用bind,這個時候,可以用第二個引數來傳遞引數,因為bind不會立即執行(不用call是因為call方法會立即執行)

// 子元件
render() {
    return (
        <ol>
          {
            this.props.todos.map(item => {
              return (
                <li key={item.id}>
                  <span>{item.title}</span>
                  <button onClick={this.props.handleDelectItem.bind(this, item.id)}>刪除</button>
                </li>
              )
            })
          }
        </ol>
    )
  }
複製程式碼
 // 父元件
 handleDelectItem = (id) => {
    const todos = this.state.todos.filter(item => item.id !== id)
    this.setState({
      todos
    })
  }
  
render() {
    return (
      <div>
          <ToDoList todos={this.state.todos} handleDelectItem={this.handleDelectItem}/>
      </div>
    );
  }
複製程式碼

3.第三種方式,使用原生的event來傳遞引數,把要傳遞的引數繫結到dom的自定義屬性上(該方法,有待完善,刪除功能還未實現)

// 子元件
handleDelectItemEvent = (e) => {
      const id = (e.currentTarget.getAttribute('data-id'))
      console.log("裡面的",id)
      this.props.handleDelectItem(id)
    }
    
render() {
    return (
        <ol>
          {
            this.props.todos.map(item => {
              return (
                <li key={item.id}>
                  <span>{item.title}</span>
                  <button data-id={item.id} onClick={this.handleDelectItemEvent}>刪除</button>
                </li>
              )
            })
          }
        </ol>
    )
  }
複製程式碼
// 父元件
handleDelectItem = (id) => {
    const todos = this.state.todos.filter(item => item.id !== id)
    this.setState({
      todos
    })
  }
  
render() {
    return (
      <div>
          <ToDoList todos={this.state.todos} handleDelectItem={this.handleDelectItem}/>
      </div>
    );
  }
複製程式碼

4.第四種方式,react官方推薦

// 子元件(ToDoItem為孫子元件)
render() {
    return (
        <ol>
          {
            this.props.todos.map(item => {
              return (
                <ToDoItem key={item.id} {...item} handleDelectItem={this.props.handleDelectItem}/>
              )
            })
          }
        </ol>
    )
  }
複製程式碼
// 孫子元件(handleRemove方法是祖先元件通過父元件在傳給孫子元件)
handleRemove = () => {
    this.props.handleDelectItem(this.props.id)
  }
  render() {
    console.log(this.props)
    return (
      <li>
        <span>{this.props.title}</span>
        <button onClick={this.handleRemove}>刪除</button>
      </li>
    )
  }
複製程式碼
// 祖先元件
handleDelectItem = (id) => {
    const todos = this.state.todos.filter(item => item.id !== id)
    this.setState({
      todos
    })
  }
  
render() {
    return (
      <div>
          <ToDoList todos={this.state.todos} handleDelectItem={this.handleDelectItem}/>
      </div>
    );
  }
複製程式碼

補充

1.defaultProps定義靜態屬性,用於設定預設的Props(外面有傳入,則用傳入的,沒有則使用預設的)

// 子元件
static defaultProps = {
    btnText: '新增'
  }
 
  render() {
    return (
      <div>
        <button onClick={this.handleAddItem}>{this.props.btnText}</button>
      </div>
    )
  }
複製程式碼

外部有傳入

// 父元件
render() {
    return (
      <div>
        <Input addToTitle={this.addToTitle} btnText='ADD'/>
      </div>
    );
  }
複製程式碼

React事件傳參深度理解

外部沒有傳入

// 父元件
render() {
    return (
      <div>
        <Input addToTitle={this.addToTitle}/>
      </div>
    );
  }
複製程式碼

React事件傳參深度理解

2.prop-types靜態屬性,用於檢測props的型別(哪裡要用就在哪裡引入)

import PropTypes from 'prop-types'
複製程式碼

注意:

注意大小寫,這裡是PropTypes,用於props型別檢查,這個需要安裝(cnpm i prop-types -S)詳情見npm官網www.npmjs.com/

static propTypes = {
    buttonText: PropTypes.string.isRequired
  }
複製程式碼

3.classname用於動態新增className到react元件,這個需要安裝(cnpm i classname -S) 詳情見npm官網www.npmjs.com/

相關文章