iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0
Modern Web

用React讓網頁動起來: React基礎與實作系列 第 7

[Day 7]用React 讓網站動起來:提升state(state lifting)

  • 分享至 

  • xImage
  •  

前兩天我介紹了React中很重要的兩個hook:useStateuseEffect,這兩個hook幫助我們讓react程式能因應使用者的動作做出變化。不過,若是今天有兩層以上的component需要用到state,那就需要用到state lifting了。
今天會透過實作一個可以新增項目的清單小程式來解釋「提升state」,可以邊看邊做看看!

取得state

若今天需要製作一個可以讓使用者新增項目的表單,有Input、List兩個component,Input供使用者輸入項目並新增,List顯示使用者新增的項目,大略可以寫出這樣的程式:

const Input = ()=>{
  return (
    <div>
     <input type="text" />
    <button>新增</button>
    </div>
  )
}

const List = ()=>{
  return (
    <ul>
      {/*放入新增項目*/}
    </ul>
  )
}

const App = ()=>{
  return (
	{/*可以使用空標籤,不一定要用div*/}
    <>
      <Input/>
      <List/>
    </>
  )
}

目前還只有架構,若要能夠使用,必須加上state才行。因此,我們先來處理Input的部分:

const Input = ()=>{
  const [input, setInput] = useState("");
  const [item, setItem] = useState([]);

	// 當input值變化時,將input值存入input state
  const inputHandler = (e)=>{
    setInput(e.target.value);
  }
	// 當按鈕點擊時,將input加入到Array中
  const clickHandler = (e)=>{
	// 使用陣列解構原本的item
    setItem([...item, input])
  }
  return (
    <div>
     <input type="text" onChange={inputHandler}/>
    <button onClick={clickHandler}>新增</button>
    </div>
  )
}

當使用者輸入值後,onChange會偵測到變化,並透過inputHandler更新input state;當使用者點擊按鈕後,onClick會執行clickHandler,將input state的值更新到item state的Array中。這樣就可以在Input中取得一個包含項目的陣列。

更新List

接下來我們想要拿上面拿到的陣列去更新空空如也的List,不過這時候就會碰到一個難題:要怎麼把Input的state傳入List呢?之前都是在同一個component中傳遞,要怎麼跨component傳遞state呢?這時候就是要提升state的時候了。
提升state概念其實並不難,由於state不能平行傳入,便將state提升-將state放在父元件中,再以props的方式傳入子元件,這樣就可以在兩個子元件中都可以使用state。
因此,我們可以修改一下上面的程式碼,把state放在App:

const App = ()=>{
  const [input, setInput] = useState("");
  const [item, setItem] = useState([]);
  
  return (
    <>
      <Input input={input} setInput={setInput} item={item} setItem={setItem}/>
      <List item={item}/>
    </>
  )
}

接著在Input中取出props使用:

const Input = ({input, setInput, item, setItem})=>{

  const inputHandler = (e)=>{
    setInput(e.target.value);
  }
  const clickHandler = (e)=>{
    setItem([...item, input])
  }
  return (
    <div>
     <input type="text" onChange={inputHandler}/>
    <button onClick={clickHandler}>新增</button>
    </div>
  )
}

接下來就可以在List元件引入item的props了!我們可以用Array.map方法loop整個Array,新建一個含項目內容的li element的Array,並直接放入ul標籤中。

const List = ({item})=>{
  // 取出item這個props,使用map
  const list = item.map(i=><li>{i}</li>);
  return (
    <ul>
      {list}
    </ul>
  )
}

這樣就大功告成了!透過state提升,可以幫助我們傳遞state到不同的component,更好的控制component。


上一篇
[Day 6]用React讓網站動起來: hooks中的useEffect
下一篇
[Day 8]用React讓網站動起來:Key
系列文
用React讓網頁動起來: React基礎與實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言