Reputation: 568
Im trying to get compare a state from the node express server with the state in the redux store. If the state is different i want to update the store state to the same value as the server state. Now im getting the problem that I can not use these hooks in a non react function. I need this to work but ive looked up the redux documentation and as far as i understand these hooks can only be used in a react function component. Is there another way to still make this work since my whole application is based on the redux state already.
import React from 'react';
import {useDispatch, useSelector} from 'react-redux';
/**
* get the gamestate from the server
* @returns {Promise<{data: any}>}
*/
async function getGamestate() {
const gameStates = await fetch('http://localhost:3000/game-state').then(response => response.json());
return {
data: gameStates,
}
}
export async function CheckIfChanged(){
const serverGameState = await getGamestate();
const clientGameState = useSelector(state => state.gameState);
if(serverGameState.data !== clientGameState){
console.log(serverGameState)
//UpdateGameState(serverGameState)
}else {
console.log("still the same")
}
}
Update: Im planning to call the function here in the mainview, this is basically a wrapper thats used in the whole application. The checkIfChanged function will be called every 5 seconds or so.
import React from 'react';
import '../../style/App.scss';
import Wrapper from '../wrapper/wrapper';
import StartView from '../startview/StartView';
import { useSelector } from 'react-redux';
function MainView(){
const gameState = useSelector(state => state.gameState);
//arround here i would call it and will be updating every 5 seconds later
checkIfChanged();
switch (gameState) {
case "notStarted":
return (
<StartView/>
);
case "video":
case "keypad":
case "puzzle":
case "completed":
case "failed":
return (
<Wrapper/>
);
default:
return (
<div className="contentArea">
<h1>Er is een fout opgetreden</h1>
</div>
);
}
}
export default MainView;
Upvotes: 3
Views: 1467
Reputation: 281626
You can't define an async method with hooks directly in render. However you can convert your function in a custom hook which can then use useSelector
and implement useEffect
to sync your changes
import React from 'react';
import {useDispatch, useSelector} from 'react-redux';
/**
* get the gamestate from the server
* @returns {Promise<{data: any}>}
*/
async function getGamestate() {
const gameStates = await fetch('http://localhost:3000/game-state').then(response => response.json());
return {
data: gameStates,
}
}
export function useCheckIfChanged(){ // not an async function
const clientGameState = useSelector(state => state.gameState);
const clientGameStateRef = useRef(clientGameState);
// Using a ref since we can't add clientGameState as a dependency to useEffect and it is bounded by closure
useEffect(() =-> {
clientGameStateRef.current = clientGameState;
}, [clientGameState]);
useEffect(() => {
setInterval(async() => {
const serverGameState = await getGamestate();
// value inside here for clientGameState will refer to the original state only and hence we are using a ref which we update in another useEffect
if(serverGameState.data !== clientGameStateRef.current){
console.log(serverGameState)
//UpdateGameState(serverGameState)
}else {
console.log("still the same")
}
}, 5000)
}, []);
}
import React from 'react';
import '../../style/App.scss';
import Wrapper from '../wrapper/wrapper';
import StartView from '../startview/StartView';
import { useSelector } from 'react-redux';
function MainView(){
const gameState = useSelector(state => state.gameState);
useCheckIfChanged(); // using the custom hook here
switch (gameState) {
case "notStarted":
return (
<StartView/>
);
case "video":
case "keypad":
case "puzzle":
case "completed":
case "failed":
return (
<Wrapper/>
);
default:
return (
<div className="contentArea">
<h1>Er is een fout opgetreden</h1>
</div>
);
}
}
export default MainView;
Upvotes: 3
Reputation: 517
You can update state by calling dispatch directly on store:
store.dispatch(actionName(values))
Redux documentation on handling store
Upvotes: 0