其實這個議題也不僅限於 React 上,Vue 上也能看到,在這兩個框架我們在撰寫時會將畫面做拆分成一塊塊小組件,然後像是拼模型一樣把畫面做組合,這時原本在同一個畫面上的資料會在各小組件中做使用,所以需要做傳遞的動作來處理,這時畫面就叫父組件,小組件們就是子組件,這是相對關係。
最一開始的做法
既然說這是相對關係,就代表子組件也是人家的父組件,子組件也是...,進入無限輪迴,所以造成只要有需要就必須一直把同一包資料從行天宮傳到外太空?這樣過程中發生什麼事情是很難追蹤的。加上有的時候甚至有別人家也需要這筆資料,但程式結構上傳不過去呀?
誕生的新做法
這時你會想說,那我有一個大爸爸(useContext)不就好了?讓他管理資料,底下都是他的孩子,都能取得;或是,我需要一個類似銀行(Redux/Zustand)的地方幫我保管資料,讓我可以方便取得資料。
Redux 解決了這樣一直傳遞的方式,我直接把資料抓出來獨立給第三方管理,誰需要誰來拿!再也不用擔心他是不是我老爸,我是不是第三者之類的事情。反正我要什麼去這裡拿就可以,也比較好追蹤針對這筆資料做的處理(因為可以把處理動作一起包在裡面)。
useContext 則將資料取得放在最外層,這樣大家對他而言都是子組件,都能從統一的地方取得資料。
這兩種方法解決了 Props drilling 的問題,讓程式在撰寫上更靈活。
哪個比較好?
選擇 Redux 或是 useContext哪個好呢?
其實如果只想用 React 原生的工具,不想增加複雜性的話,可以使用 useContext 處理 Props drilling 議題。不過,這時會產生一個議題,假如 useContext 內的資料更新呢...?沒錯,這時 React 會無差別重新渲染,不管你是不是我資料的用戶我都重新渲染,這種在龐大的應用上可不是好事。
當然你還是可以細膩到只包裹可能需要用到他的組件就好,所以使用 Redux 的其中一個好處是,在資料有改變後,可以僅針對有使用到的組件做重新渲染。
回頭想一下
這時候我們已經知道這兩個工具都是為了處理 Props drilling 產生的問題,那...有沒有一種可能,我其實根本不在乎這個問題,或是,我可以調整架構讓他不會產生這麼多層級?
答案是肯定的,什麼選擇都可以做,反正程式不會因此壞掉。不過你可能就要很有把握自己的設計非常彈性,也能好好控管自己的參數。
所以怎麼做取捨就看個人。