Reactjs 非反应函数中的Redux

Reactjs 非反应函数中的Redux,reactjs,redux,Reactjs,Redux,我正在尝试将node express服务器的状态与redux存储中的状态进行比较。如果状态不同,我希望将存储状态更新为与服务器状态相同的值。现在我遇到了一个问题,我不能在非react函数中使用这些钩子。我需要这样做,但我查阅了redux文档,据我所知,这些挂钩只能用于react函数组件。因为我的整个应用程序已经基于redux状态,所以还有其他方法可以让它继续工作吗 import React from 'react'; import {useDispatch, useSelector} from

我正在尝试将node express服务器的状态与redux存储中的状态进行比较。如果状态不同,我希望将存储状态更新为与服务器状态相同的值。现在我遇到了一个问题,我不能在非react函数中使用这些钩子。我需要这样做,但我查阅了redux文档,据我所知,这些挂钩只能用于react函数组件。因为我的整个应用程序已经基于redux状态,所以还有其他方法可以让它继续工作吗

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")
    }
}
从“React”导入React;
从'react redux'导入{useDispatch,useSelector};
/**
*从服务器获取游戏状态
*@returns{Promise}
*/
异步函数getGamestate(){
const gameStates=等待获取('http://localhost:3000/game-然后(response=>response.json());
返回{
数据:游戏状态,
}
}
导出异步函数CheckIfChanged(){
const serverGameState=wait getGamestate();
const clientGameState=useSelector(state=>state.gameState);
if(serverGameState.data!==clientGameState){
console.log(服务器游戏状态)
//UpdateGameState(服务器游戏状态)
}否则{
console.log(“仍然相同”)
}
}
更新: 我计划在mainview中调用这个函数,它基本上是一个包装器,用于整个应用程序。checkIfChanged函数将每隔5秒左右调用一次

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;
从“React”导入React;
导入“../style/App.scss”;
从“../Wrapper/Wrapper”导入包装器;
从“../StartView/StartView”导入StartView;
从'react redux'导入{useSelector};
函数MainView(){
const gameState=useSelector(state=>state.gameState);
//在这里,我会调用它,并将每5秒更新一次
checkIfChanged();
开关(游戏状态){
案例“未启动”:
返回(
);
案例“视频”:
案例“键盘”:
案例“谜题”:
案件“已完成”:
案例“失败”:
返回(
);
违约:
返回(
她是个好朋友
);
}
}
导出默认主视图;

您可以通过直接在门店上调用dispatch来更新状态:

store.dispatch(actionName(values))

不能直接在渲染中定义带有挂钩的异步方法。但是,您可以在自定义挂钩中转换函数,然后使用
useSelector
并实现
useffect
来同步更改

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)
    }, []);

}
从“React”导入React;
从'react redux'导入{useDispatch,useSelector};
/**
*从服务器获取游戏状态
*@returns{Promise}
*/
异步函数getGamestate(){
const gameStates=等待获取('http://localhost:3000/game-然后(response=>response.json());
返回{
数据:游戏状态,
}
}
导出函数useCheckIfChanged(){//不是异步函数
const clientGameState=useSelector(state=>state.gameState);
const clientGameStateRef=useRef(clientGameState);
//使用ref,因为我们不能将clientGameState作为依赖项添加到useEffect,并且它受闭包限制
使用效果(()=->{
clientGameStateRef.current=clientGameState;
},[clientGameState]);
useffect(()=>{
setInterval(异步()=>{
const serverGameState=wait getGamestate();
//这里clientGameState中的值仅指原始状态,因此我们使用的是一个ref,我们在另一个useffect中更新了该ref
if(serverGameState.data!==clientGameStateRef.current){
console.log(服务器游戏状态)
//UpdateGameState(服务器游戏状态)
}否则{
console.log(“仍然相同”)
}
}, 5000)
}, []);
}

从“React”导入React;
导入“../style/App.scss”;
从“../Wrapper/Wrapper”导入包装器;
从“../StartView/StartView”导入StartView;
从'react redux'导入{useSelector};
函数MainView(){
const gameState=useSelector(state=>state.gameState);
useCheckIfChanged();//在此处使用自定义挂钩
开关(游戏状态){
案例“未启动”:
返回(
);
案例“视频”:
案例“键盘”:
案例“谜题”:
案件“已完成”:
案例“失败”:
返回(
);
违约:
返回(
她是个好朋友
);
}
}
导出默认主视图;

您能展示一下如何使用和在哪里使用吗CheckIfChanged@ShubhamKhatri在这一点上,我正在测试我是否可以让这个函数工作,所以我还没有真正使用它。然而,我计划在我的App.js中使用它,它基本上是整个应用程序的包装器,我将把它添加到帖子中
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;