iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
0
自我挑戰組

React初心者30天的探索之路系列 第 9

[Day 09] React State & props

  • 分享至 

  • xImage
  •  

State

state 為自身component 存放資料的地方,管理內部狀態,格式為一個物件,以class component來說,在建立自身的component state之前記得在constructor要先呼叫super(),不然會取不到this

如果沒執行super ,就調用this, 畫面會直接報錯提醒你

如果是create react app的話不需要寫constructor了,因為已經引用了@babel/plugin-proposal-class-properties套件,可以直接寫state,但因為練習的關係,接下來的範例還是會乖乖寫constructor

這是省去constructor的寫法

class StateExample extends Component{
  state = {
    count:0 //初始值
  }
}

利用this.state.count就可以取到值,用setState可以改變state

setState傳入兩個參數 第一個是物件,第二個是callback function

利用setState來改變原本的state,記得要傳入的是一個物件,當state偵測到資料更動的時候就會觸發render讓畫面重新渲染。

class StateExample extends Component{
    constructor(){
        super() 
        this.state = {
            count:0 //初始值
        }
    }
    addCount = () => {
        let num = this.state.count + 1
        this.setState({ count: num}) //改變state
    }
    render(){
        return(
            <Fragment>
                <h1>{this.state.count}</h1>
                <button onClick={this.addCount}>add</button>
            </Fragment>
        )
    }
}

如果我不用setState , 直接改state的值呢?你就會發現畫面一動也不動,因為React並不知道state已經被修改了,所以一定要用setState!

addCount = () => {
  this.state.count++
} 
//這樣是不會有反應的

另外,我在官網看到一個蠻有趣的例子,試著實作一下,點了按鈕後會連續觸發三次+1的function,預期應該會在畫面上看到3這個數字,結果,居然數字只有1!原來會造成這樣的原因是setState是非同步的,如果要解決這樣的問題該怎麼做?


handleClick = () =>{
    this.addCount()
    this.addCount()
    this.addCount()
}

可以傳入一個更新用的function讓你可以取到當前state,而非舊的state

    addCount = () => {
        this.setState((state)=>({ count: state.count + 1}))
    }

props

props 為子組件接受父組件的溝通管道,是唯獨的不可異動

父組件利用title屬性傳入值

<PropsExample title='member center' />

子組件用props取的上面傳下來的title

class PropsExample extends Component{
    constructor(){
        super()
    }
    render() {
        return (
            <Fragment>
                 <h1>{this.props.title}</h1>
            </Fragment>    
         )
     }
 }

假設我試圖想要從子組件改變this.props.title

 return (
    <Fragment>
         <h1>{this.props.title}</h1>
         <button onClick={()=>{this.props.title='record'}}>change</button>
    </Fragment>    
 )
 

就會報錯了!告訴你這是個唯獨的值,因此想要改動的話,還是乖乖從父組件異動吧!或者將setState的方法透過props丟給子組件,讓子組件呼叫也是可以達成修改props的目的

另外再傳入props的時候,也可以順便定義一下型別,確保收到的props是正確的,React.PropTypes已經被棄用了,目前官網建議安裝prop-types來檢查型別

import PropTypes from 'prop-types';

class PropsExample extends Component{
   constructor(){
       super()
   }
   render() {
       return (
           <Fragment>
                <h1>{this.props.title}</h1>
           </Fragment>    
        )
    }
}

PropsExample.propTypes = {
  title:PropTypes.string
}

假設我故意傳數字進來,就會報錯了

另外還有一種寫法可以傳入各種元素進去,乍看還蠻像vue的slot(雖然兩個功能不太一樣啦..

class PropsExample extends Component {
   constructor() {
       super()
   }
   render() {
       return (
           this.props.children
       )
   }
}

父組件的結構如下

<PropsExample>
  <ul>
    <li>apple</li>
    <li>banana</li>
    <li>lemon</li>
  </ul>
</PropsExample>

就能將< PropsExample >標籤內的html當作props丟給子組件接收了
以上就是關於State和props的簡單介紹!


上一篇
[Day 08] React lifeCycle 生命週期
下一篇
[Day 10] React CSS 最重要的小事(上)
系列文
React初心者30天的探索之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言