从减速器中的服务器获取

Fetching from a server from within a reducer

我正在使用 React 和 Immer 制作一个非常简单的前端。我需要显示的数据是简单的嵌套 Json。 json 以状态存储在树的顶部,使用 immer 的简单缩减器允许编辑 json。 我想添加一个按钮来触发服务器上 json 的 json 状态的刷新。

function SectionRender(props){
    
      const [jsonData, jsonDispatch] = useImmerReducer(jsonDataReducer, props.json);
      const handleRefreshClick = () => jsonDispatch({ type:"refresh"})
return  <div> 
        /* rest of display */ 
        <button onClick={handleRefreshClick}>Reinitialiser</button>
        </div>
}

这是顶部。它与减速器一起使用:

function jsonDataReducer(draft, action) {
    switch (action.type) {
        /* other cases for edit */
        case "refresh":
            const newStuff = getServerData().then(
            (value) => {
                console.log("we got something");
                //something that would modify the state here??
            },
            () => {
                console.log("no server response")           
            })
            break;
        default:
            break;
    }
}

我尝试返回“新内容”值。但是由于它是一个承诺,所以整个状态都变成了一个承诺,当它试图渲染时,其余的显示崩溃。在 .then() 中修改草稿似乎也不起作用(大概是因为该函数早就返回了可变草稿)。

很明显我可能没有正确地构造事物,但我想不出我应该如何构造它,或者我应该做什么来允许从异步函数调用修改状态。

Reducer 是纯函数,您应该避免在其中添加任何副作用,例如异步调用。因此,请尝试将此异步逻辑排除在减速器之外(在 handleRefreshClick 期间),一旦您收到异步调用返回的输出,然后使用从调用返回的数据调度操作以修改状态。

喜欢

const handleRefreshClick = () => {
    getServerData().then(
        (value) => {
            jsonDispatch({ type:"refresh", data: value})
        },
        () => {
            console.log("no server response")           
        })
}