天天看點

關于react的元件之間傳值

react中不依賴redux等這些進行狀态管理的話,主要是有父元件給子元件傳值,子元件給父元件傳值,還有兄弟元件之前的傳值

關于react的元件之間傳值

這是一個評論功能的小栗子,非常适合來說明元件之前傳值的問題

首先上個項目檔案目錄結構

關于react的元件之間傳值

這裡一共有四個元件Comment是最外層的容器元件,CommentInput是負責輸入,

其餘兩個負責評論展示

子元件給父元件傳值

先了解一下定義:react中state改變了,元件才會update。父寫好state和處理該state的函數,同時将函數名通過props屬性值的形式傳入子,子調用父的函數,同時引起state變化。子元件要寫在父元件之前

子元件與父元件之前存在繼承的關系,是以子元件可以調用父元件的方法。

class CommentInput extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      username: "",
      content: ""
    }
  }
  show = () => {
    if (this.props.onSubmit) {
      const { username, content } = this.state
      this.props.onSubmit({username, content})
    }
    this.setState({ content: "" })
  }
  handleContent = (e) => {
    this.setState(
      { content: e.target.value }
    )
  }
  handleUserName = (e) => {
    this.setState(
      { username: e.target.value }
    )
  }
  render() {
    return (
      <div className="comment-input">
        <div className="input-filed">
          <span className="input-filed-name">使用者名:</span>
          <div className="input-filed-content">
            <input type="text" value={this.state.username} onChange={this.handleUserName} />
          </div>
        </div>
        <div className="input-filed">
          <span className="input-filed-name">評論内容:</span>
          <div className="input-filed-content">
            <textarea value={this.state.content} onChange={this.handleContent} />
          </div>
        </div>
        <div className="input-filed-btn">
          <button onClick={this.show}>釋出</button>
        </div>
      </div>
    );
  }
}
                

注意類中的show()方法

show = () => {
    if (this.props.onSubmit) {
      const { username, content } = this.state
      this.props.onSubmit({username, content})
    }
    this.setState({ content: "" })
  }
                

同樣我們給出父元件CommentApp的代碼

class CommentApp extends Component {
  constructor(props) {
    super(props)
    this.state = {
      comments: []
    }
  }
  handleSubmit = (comment) => {
    if (!comment) return
    if (!comment.username) return alert('請輸入使用者名')
    if (!comment.content) return alert('請輸入評論内容')
    this.state.comments.push(comment)
    this.setState(
      {
        comments: this.state.comments
      }
    )
  }
  render() {
    return (
      <div className="wrapper">
        <CommentInput onSubmit={this.handleSubmit} />
        <CommentList comments={this.state.comments} />
      </div>
    );
  }
}
                

同樣請注意父元件中的onSubmit={this.handleSubmit} 方法,是不是發現了子元件中有this.props.onSubmit這麼個語句,這個原理就是子元件給父元件props傳值時通過父元件定義的方法去改變父元件的state

父元件給子元件傳值

相較于子元件給父元件傳值來說,父元件給子元件傳值就簡單的多了,我們都知道class有構造函數constructor,通常我們是這麼寫的。以父元件CommentApp為例

constructor(props) {
    super(props)
    this.state = {
      comments: []
    }
  }
                

其中的props就是從父元件中繼承的,裡面可以有屬性、方法。那父元件是怎麼給子元素傳入的呢?繼續往下看:還是父元件CommentApp為例

render() {
    return (
      <div className="wrapper">
        <CommentInput onSubmit={this.handleSubmit} />
        <CommentList comments={this.state.comments} />
      </div>
    );
  }
                

代碼中,父元件給CommentList傳了一個叫comments={this.state.comments} comment的屬性,再看子元件CommentList中

class CommentList extends React.Component {
    static defaultProps = {
        comments: []
    }
    render() {
        return (
            <div>
                {this.props.comments}
                {this.props.comments.map((comment, i) => {
                    return (
                        <Comment comment={comment} key={i} />
                    )
                })}
            </div>
        )
    }
}
                

CommentList元件中使用this.props.comments 就能把comments取出,是不是簡單許多。

兄弟元件傳值

隻聽說過父子元件之間的傳值,卻是不知道兄弟元件怎麼傳值,是不是需要用到第三方的狀态管理呢?事實上,元件的狀态多了對于我們來說并不是什麼好事,因為狀态多容易産生混亂,雖然說第三方的狀态管理能我們省下不少事,但是也不能盲目的使用。如果元件之間不是多層嵌套,傳值可以直接react解決

這個例子中CommentsList和CommentsInput就是一個兄弟元件,公共附件即為CommentApp。是以CommentApp就是兩個子元件“溝通”的橋梁

關于react的元件之間傳值

回頭看,CommentInput 需要把輸入的内容在CommentIist中顯示處理啊,就需要每次都把内容傳給CommentIist。但是CommentInput 先把值傳給了父元素CommentApp

CommentInput中片段

show = () => {
    if (this.props.onSubmit) {
      const { username, content } = this.state
      this.props.onSubmit({username, content})
    }
    this.setState({ content: "" })
  }
                

content就是我們擷取的内容。

CommentApp代碼片段

render() {
    return (
      <div className="wrapper">
        <CommentInput onSubmit={this.handleSubmit} />
        <CommentList comments={this.state.comments} />
      </div>
    );
  }
                

這就是兄弟元件之間的傳值方式。

本文的例子來自于《React.js 小書》,學習過程中覺得這個例子可以很好的說明元件之間的傳值關系,如需源碼,可以留言哈,待我“收拾”下GitHub倉庫項目後放在留言區

這是第一次寫技術部落格,如有錯誤歡迎指正,有什麼問題也可以給我留言哦!