I’m building a hook for data ordering, and it can receive state and setState from outside, defined by the user, but if they are not passed, I use an internal useState declaration.
But is this approach recommended? As follows:
export function useMaterialTableSort(data, columns, orderState, setOrderState) {
if (orderState && setOrderState) {
var columnOrder = orderState
var setColumnOrder = setOrderState
}
else if (!orderState && !setOrderState) {
var [columnOrder, setColumnOrder] = useState({})
}
else {
throw Error("orderState and setOrderState must be defined!")
}
// rest of the component that uses columnOrder and setColumnOrder state
}
The other alternative would be to use an aligned state to update according to the outside state, but this would cause two renders
export function useMaterialTableSort(data, columns, orderState, setOrderState) {
const [columnOrder, setColumnOrder] = useState(orderState || {})
useEffect(() => {
if (typeof orderState === "object") {
setColumnOrder(orderState)
}
}, [orderState])
// In the rest of the component, instead of using setColumnOrder,
// which would cause a rendering loop, I would use setOrderState,
// which is an outside state
}
2
Answers
Calling
useState
conditionally breaks the rules of React hooks – it may work in practice, because a the caller of your function will likely consistently either supply or not supplyorderState
/setOrderState
, but I would not recommend it.You can re-write your hook like this:
since at the end of the day you want to order data you can just order it internally and return setColumnOrder to allow the user to also do moification outside the hook without needing to redeclare a use State
}