如何與組件的狀態互動

設置默認狀態

在組件的構造函數中,初始化this.state。例如,BlogPostExcerpt 組件可能有一個clicked的狀態:

class BlogPostExcerpt extends Component {
  constructor(props) {
    super(props)
    this.state = { clicked: false }
  }

  render() {
    return (
      <div>
        <h1>標題</h1>
        <p>描述</p>
      </div>
    )
  }
}

訪問狀態

可以通過引用this.state.clicked來訪問 clicked 狀態:

class BlogPostExcerpt extends Component {
  constructor(props) {
    super(props)
    this.state = { clicked: false }
  }

  render() {
    return (
      <div>
        <h1>標題</h1>
        <p>描述</p>
        <p>點擊: {this.state.clicked}</p>
      </div>
    )
  }
}

改變狀態

永遠不要使用以下方式修改狀態:

this.state.clicked = true

相反,應始終使用setState(),並將一個對象作為參數傳遞給它:

this.setState({ clicked: true })

該對象可以包含狀態的子集或超集。只有傳遞的屬性才會被修改,忽略的屬性將保持當前狀態。

為什麼應該始終使用setState()

使用此方法的原因是,React 知道狀態已經改變。然後,它將啟動一系列事件,導致該組件被重新渲染,以及任何DOM的更新。

單向數據流

狀態始終由一個組件擁有。受此狀態影響的任何數據只能影響它下面的組件:它的子組件。

更改組件的狀態永遠不會影響其父組件、兄弟組件或其他應用中的任何其他組件:只會影響它的子組件。

這就是為什麼狀態通常在組件樹中向上移動的原因。

將狀態向上移動到樹中

根據單向數據流規則,如果兩個組件需要共享狀態,則需要將狀態向上移動到共同的祖先組件中。

許多時候,最接近的祖先是管理狀態的最佳位置,但這不是強制性的規則。

通過 props 將狀態傳遞給需要該值的組件:

class Converter extends React.Component {
  constructor(props) {
    super(props)
    this.state = { currency: '€' }
  }

  render() {
    return (
      <div>
        <Display currency={this.state.currency} />
        <CurrencySwitcher currency={this.state.currency} />
      </div>
    )
  }
}

可以通過將一個具有變異函數的子組件作為 props 傳遞下去來改變狀態:

class Converter extends React.Component {
  constructor(props) {
    super(props)
    this.state = { currency: '€' }
  }

  handleChangeCurrency = event => {
    this.setState({ currency: this.state.currency === '€' ? '$' : '€' })
  }

  render() {
    return (
      <div>
        <Display currency={this.state.currency} />
        <CurrencySwitcher
          currency={this.state.currency}
          handleChangeCurrency={this.handleChangeCurrency}
        />
      </div>
    )
  }
}

const CurrencySwitcher = props => {
  return (
    <button onClick={props.handleChangeCurrency}>
      當前貨幣{props.currency}更改它
    </button>
  )
}

const Display = props => {
  return <p>當前貨幣{props.currency}</p>
}