How useStoreState is referring values in react? - reactjs

I am pretty new to react and easy-peasy, I am stuck with one implementation with useStoreState.
I just want to understand how the useStoreState and useStoreAction work in the below code and how state.AdminCompanyInfo and action.AdminCompanyInfo are getting resolved.
I don't find any simple-to-understand example. Please help.
here is the code
const AdminCompanyInfo = () => {
var userType = isDesignerUser ? 1 : 2;
const [hideInactiveUser, setHideInactiveUser] = useState();
const {
roles: { data: roles },
companyUsers: state,
inactiveUserSetting: { response: orgSetting },
} = useStoreState(state => state.AdminCompanyInfo);
const {
companyUsers: { fetch },
companyUsers: actions,
roles: { fetch: fetchRoles },
inactiveUserSetting: { update: updateOrgSetting },
} = useStoreActions(actions => actions.AdminCompanyInfo);
useEffect(() => {
fetchRoles(userType);
fetch();
}, []);
}

Related

Testing custom hook React

I created a hook
export function useRedirectStartParams() {
const scenarios: IScenario[] = useSelector(scenariosSelector);
const block: IBlockItem = useSelector(selectedBlockSelector);
const [redirects, setRedirects] = useState<IDropdownEl[]>([]);
useEffect(() => {
const newRedirects =
block?.block_data?.redirects?.map((block: any) => {
const scenarioName = scenarios.find(
(scenario) => scenario.id === block.scenario_id
)?.name;
return {
name: scenarioName,
val: {
scenarioId: block.scenario_id,
blockId: block.id,
},
};
}) || [];
setRedirects(newRedirects);
}, [block, scenarios]);
return { redirects };
}
use it in my component
const { redirects } = useRedirectStartParams();
and then try to test it with jest like this
import { useRedirectStartParams } from "#hooks/useRedirectStartParams";
jest.mock("#hooks/useRedirectStartParams");
beforeEach(() => {
useRedirectStartParams.mockReturnValueOnce({
redirects: [{ name: "ad", val: "123" }],
});
})
but got error that redirects are undefined.
I also tried to mock hook this way
jest.mock("#hooks/useRedirectStartParams", () => jest.fn());
And it didn't help me
I expect that redirects won't be undefined. Not renderHook. i want to mock value of hook for component

React useEffect loop: circular dependency

I'm trying to call a function every time that function's parameters change and this has generated a loop that I don't know how to solve. I've tried implementing this in several ways, such as:
const [fromAmount, setFromAmount] = useState(1);
const [fromToken, setFromToken] = useState<keyof typeof tokens>("WBNB");
const [toToken, setToToken] = useState<keyof typeof tokens>("CAKE");
const path = useMemo(
() => [tokens[fromToken].address, tokens[toToken].address],
[fromToken, toToken]
);
const setAmountsOutParams = useCallback(() => {
if (fromAmount > 0) {
getAmountsOut.setParams({
amountIn: ethers.utils.parseUnits(String(fromAmount), 18),
path,
});
}
}, [fromAmount, path]);
useEffect(() => {
setAmountsOutParams()
}, [setAmountsOutParams]);
As context, I have a hook that provides me with the getAmountsOut, and this is the code regarding it:
const [paramsGetAmountsOut, setParamsGetAmountsOut] = useState({
amountIn: ethers.utils.parseUnits('0', 18),
path: ['', ''],
});
const { data: dataGetAmountsOut } = useContractRead({
...swapper,
functionName: 'getAmountsOut',
args: [paramsGetAmountsOut.amountIn, paramsGetAmountsOut.path],
});
const getAmountsOut = {
data: dataGetAmountsOut,
setParams: setParamsGetAmountsOut,
};
How to solve it?

I want to process setState at once

enter image description here
I want to count "indie" and "action" at the same time when the button is clicked. However, the only real application is "action". Please tell me how.
This is my solution to your problem
import React, { useState, useEffect } from "react";
const games = [
{ id: 1, genre: ["indie", "action"] },
{ id: 2, genre: ["indie"] },
{ id: 3, genre: ["action"] }
];
function ButtonComponent(props) {
const { genre, fn } = props;
return <button onClick={() => fn(genre)}>Click</button>;
}
function TestPage() {
const [genre, setGenre] = useState({ indie: 0, action: 0 });
const addGenrecount = (genres) => {
setGenre((previousState) => {
let { indie, action } = previousState;
genres.forEach((genre) => {
if (genre === "indie") indie = indie + 1;
if (genre === "action") action = action + 1;
});
return { indie, action };
});
};
useEffect(() => console.log("genre", genre), [genre]); // Logs to the console when genre change
return games.map((game) => {
const { id, genre } = game;
return <ButtonComponent key={id} genre={genre} fn={addGenrecount} />;
});
}
export default TestPage;
You may also go to codesandbox to test the demo
https://codesandbox.io/s/xenodochial-dirac-q01h4?file=/src/App.js:0-968
Just Friendly Tip:
If you need help regarding react I recommend to upload your code to codesandbox so that we can easily reproduce or solve the problem

How to add some option to a select box above all mapping in React?

I want to add an All Option to my existing select box.
Select box is creating with some API data. With the API data set I want to add an ALL option above.
This is my code.
const useChemicals = () => {
const [data, setData]: any = useState([]);
useEffect(() => {
const getChemicalsData = async () => {
try {
const results = await searchApi.requestChemicalsList();
if (results.data) {
let groupCount = 0;
const chemList: any = [];
results.data.data.chemicals.map((chemical: any, index: number) => {
if (chemical.key === '') {
chemList.push({
label: chemical.value,
options: [],
});
}
});
results.data.data.chemicals.map((chemical: any, index: number) => {
if (chemical.key === '') {
if (index > 1) {
groupCount += 1;
}
} else {
chemList[groupCount].options.push({
label: chemical.value,
value: chemical.key,
});
}
});
setData([...chemList]);
}
} catch (e) {}
};
getChemicalsData();
}, []);
return data && data;
};
export default useChemicals;
How can I add this. Please help me, I am new to React.

React-Apollo: Recommended way of subscribing to multiple events that doesn't require UI updates

So i want to subscribe to multiple events for the current logged user.
I've extracted the subscriptions to a separate function that update my logged user state from inside and returns an array of subscriptions.
Now i wanted to know is there a different / better way of doing this ?
Is this the correct / recommended way of approaching this problem ?
Current implementation
export const subscribeToCurrentUserUpdates = (setLoggedUser) => {
const friendRequestObserver$ = apolloClient.subscribe(
{ query: queries.NEW_FRIEND_REQUEST },
);
const followersUpdatesObserver$ = apolloClient.subscribe(
{ query: queries.FOLLOWERS_UPDATES },
);
const acceptedFriendRequestObserver$ = apolloClient.subscribe(
{ query: queries.ACCEPTED_FRIEND_REQUEST },
);
const friendRequestSubscription = friendRequestObserver$.subscribe({
next: ({ data: { newFriendRequest } }) => {
Alert.success(`${newFriendRequest.username} just sent you a friend request`);
setLoggedUser((loggedUser) => {
loggedUser.incomingFriendRequests.unshift(newFriendRequest._id);
});
},
error: err => console.error(err),
});
const followersUpdatesSubscription = followersUpdatesObserver$.subscribe({
next: ({ data: { followersUpdates: { follower, isFollow } } }) => {
if (isFollow) {
Alert.success(`${follower.username} is now following you`);
}
setLoggedUser((loggedUser) => {
isFollow
? loggedUser.followers.unshift(follower._id)
: loggedUser.followers.splice(loggedUser.followers.indexOf(follower._id), 1);
});
},
error: err => console.error(err),
});
const acceptedFriendRequestSubscription = acceptedFriendRequestObserver$.subscribe({
next: ({ data: { acceptedFriendRequest: newFriend } }) => {
Alert.success(`${newFriend.username} just accepted your friend request!`);
setLoggedUser((loggedUser) => {
loggedUser.friends.push(newFriend._id);
loggedUser.sentFriendRequests.splice(
loggedUser.sentFriendRequests.indexOf(newFriend._id), 1,
);
});
},
error: err => console.error(err),
});
return [
friendRequestSubscription,
followersUpdatesSubscription,
acceptedFriendRequestSubscription,
];
};
The way i subscribe from my component
const App = () => {
const currentUserSubscriptionRef = useRef();
useEffect(() => {
if (loggedUser && !currentUserSubscriptionRef.current) {
currentUserSubscriptionRef.current = subscribeToCurrentUserUpdates(
setLoggedUser,
);
}
if (!loggedUser && currentUserSubscriptionRef.current) {
currentUserSubscriptionRef.current.forEach((subscription) => {
subscription.unsubscribe();
});
currentUserSubscriptionRef.current = null;
}
}, [loggedUser, setLoggedUser]);
}

Resources