如何获取 React 组件的状态以实现全局保存按钮

How to obtain state of a React Component to implement a global Save-Button

我们开发了一个可重用的 table-like 组件,具有 Reacts 功能组件样式。 table 使用 React.useReducer 保存、管理和验证它的状态。 在每一行中都有几个输入字段、复选框和操作按钮来修改 row/table-state.

现在 GUI 中的其他地方有一个保存按钮(不是 table 的子项)。 如何从 table 检索状态,以便将其(与其他一些数据一起)发送到 REST 端点以实现持久性?

我们实际的解决方案是一个回调函数,它将被设置为 table 上的一个属性。 每次渲染后从 table-component 内部调用此函数以发布当前状态的副本。 现在此回调函数的所有者获取并保存此数据,以便它在保存按钮的范围内可用。

function ComponentWrapper(props)
{
    const dataRef = React.useRef(props.initialData);

    function onDataUpdate(newData) {
        dataRef.current = newDate;
    }
    
    function saveData() {
        // send dataRef.current to REST-Endpoint
    }
    
    return (
        <div>
            <MyTable onDataUpdate={onDataUpdate}></MyTable>
            ...
            <button onClick={(e) => sendData()} name="save">Save</button>
        </div>
    );
}
    
function MyTable(props)
{
    const [state, dispatch] = useReducer(..., props.initialData)

    // ... some code to dispatch state changing actions

    useEffect(() => {
        const copyOfState = { ...state }
        props.onDataUpdate(copyOfState);
    });
   
    return (
        // table markup goes here ...
    );
}

这确实有效,但我们相信对于此类用例可能有更好的方法。 我们不想将状态从 table 提升到 ComponentWrapper,因为 table 应该是可重用的,并且保存按钮可能位于 GUI 中完全不同的位置(例如,在工具栏或一个菜单)。

对此有什么想法吗?提前致谢。

如果您的 table 当前正在管理自己的状态,那么您需要提升该状态,或将其移至某个全局存储区。正如您所说,将保存功能作为回调从树上的某个组件传递,该组件也是保存按钮的父级。

但更优雅和用户友好的解决方案是使用一些 context, or use redux.

使用上下文,您的保存函数可以将该值传递给上下文对象,该对象可以在树的其他位置检索。有很多关于如何做到这一点的好文章 - here is one, and here is another.

Redux 与此类似,并且已成为您最喜欢做的事情。您可以使用 redux reducer 将 table 数据保存到全局存储,然后您的 'save' 按钮可以调用从存储中检索此数据并将其发送到您的 REST 端点,而不管它在树到 table。在需要跨多个组件协调状态的大型应用程序中,它绝对是首选。