在Day20我們學會了使用Props傳遞資料,但你是否想過,如果今天我們的組件階層過於多,這樣會導致一些不必要的組件,也要幫忙傳遞資料。
目前我要從A組件傳遞資料到D組件,但中間的B、C組件是不需要這些資料的。
於是React就有了全域資料的組件,方便我們使用。
今日會學習到的Hooks
Context docs
首先我們必須建立一個全局的組件,從React引入createContext
//globalName.js
import { createContext } from "react";
export const nameContext = createContext(null)
然後我們需要把這個組件變成父組件。
這邊我們把剛剛的組件引入,並且在組件中我們要使用 .Provider,並且我們要給予value
// App.js
import React from 'react'
import Child from '../Components/Child'
import { nameContext } from '../GlobalName'
function App() {
const value = 'Ian'
return (
<nameContext.Provider value={value} >
<Child />
</nameContext.Provider>
)
}
export default App
到了我們的子組件,也必須把全局的組件引入,並且使其變成參數傳入Hook
const value = useContext(MyContext);
import React, {useContext} from 'react'
import {nameContext} from '../GlobalName'
function Child() {
const name = useContext(nameContext)
return (
<div>
My name is : {name}
</div>
)
}
export default Child
我們可以把useContext給值的name打印出來,可以發現是傳入的value。當然,你傳入何種資料型態,取用時也是同等的。
useReducer docs
我們前面有學過useState來使用組件內的狀態,而現在要學的useReducer不同於useState直接操作數值的方式。
而是使用觸發動作,進而達到目標與需求。
這也可以解決當一次操作會有許多動作時,使用useReducer可以更好的了解資料流的去向。
const [state, dispatch] = useReducer(reducer, initialArg, init);
首先我們建立一個reducer的函式。
當然,你要取其他名子也可以,但建議還是維持reducer會比較明確。
// reducer.js
const countReducer = (state, action) => {
switch (action) {
case 'increase':
return state + 1
case 'decrease':
return state - 1
default:
return state
}
}
export default countReducer
並且把countReducer引入進我們的主程式
// App.js
import React, {useReducer} from 'react'
import countReducer from '../reducer'
function App() {
let initialize = 0
const [state, dispatch] = useReducer(countReducer,initialize)
return (
<div>
<button onClick={() => dispatch('increase')}>Add</button>
<button onClick={() => dispatch('decrease')}>Minus</button>
<p>{state}</p>
</div>
)
}
export default App
而我們在onClick事件中各自綁定我們預設好的dispatch,各司其職,使其有很明確的操作動作。
其實學到現在,應該可以慢慢理解到,針對你的需求使用各種不同的API,而不是盲從搜尋最佳解。
這才是學習程式必要的思考,也是為什麼我的文章主旨會說明,"知道什麼問題,並且了解為什麼要使用此方法解決它"!!!