Utilizing Javascript proxy this custom changes the default way of setting state in React which is a function that requires a function.
By using this hook simply assigning value to state will result same as setState. It’s really a wrapper around useState.
Here is usProxyState simple 20 lines of code.
https://github.com/Sourav9063/watchtogether/blob/master/src/helper/hooks/useProxyState.js
import { useState } from "react";
export const useProxyState = (initialState = {}) => {
if (typeof initialState != "object") {
initialState = { value: initialState };
}
const [state, setState] = useState(initialState);
state.setState = setState;
const handler = {
set(_, prop, value) {
if (value !== state[prop]) {
setState((state) => {
return { ...state, [prop]: value };
});
}
return Reflect.set(...arguments);
},
};
const stateProxy = new Proxy(state, handler);
return stateProxy;
};
Notes
For Object type state, direct assignment will work i.e.
state.count
. Any other type state you can access and modify viastate.value
You can get the default setState in
state.setState()
const state1 = useProxyState({ count: 1 });
const state2 = useProxyState(1);
//...
state1.count = 100;
state2.value = 200;
Comparisons
useProxyState
"use client";
import { useProxyState } from "@/helper/hooks/useProxyState";
import styles from "../page.module.css";
export default function Personal() {
const state1 = useProxyState({ count: 1 });// object
const state2 = useProxyState(state1.count * 2);// not object
state2.value = state1.count * 2; //no need for useEffect. And cannot be changed else where.
return (
<>
<main className={styles.main}>
<div className={styles["cards"]}>
<button
onClick={() => {
state1.count++; //simple assignment will update the state
}}
>{state1.count}
</button>
<button
onClick={() => {
state2.value++;// for values other than object, use value.
}}
>{state2.value}
</button>
</div>
</main>
</>
);
}
Default useState
"use client";
import styles from "../page.module.css";
import { useEffect, useState } from "react";
export default function Personal() {
const [state3, setState3] = useState({
count: 1,
});
const [state4, setState4] = useState(state3.count * 2);
useEffect(() => {
setState4(state3.count * 2);
return () => {};
}, [state3.count]);
return (
<>
<main className={styles.main}>
<div className={styles["cards"]}>
<button
onClick={() => {
setState3((state) => ({ ...state, count: state.count + 1 }));
}}
>
useState {state3.count}
</button>
<button
onClick={() => {
setState4((state) => {
return state + 1;
});
}}
>
useState {state4}
</button>
</div>
</main>
</>
);
}
GITHUB: sourav9063
WEBSITE: https://sourav9063.github.io/
LINKDIN: sourav-ahmed
Top comments (0)