React中API响应返回前禁用按钮,子组件按钮无法同步状态如何解决
问题根源
你当前实现的useNewExportRequestStore是普通React自定义Hook,每个组件调用该Hook时,内部的useState会生成完全独立的状态实例,不会跨组件共享。因此父组件NewSwCalculation和子组件NewChildSwCalculation拿到的isCalculationLoadHw是两个互不关联的变量,父组件修改状态不会同步到子组件。
解决方案(原生React Context方案)
1. 改造自定义Hook为Context共享状态
// src/Contract/NewExportRequestStore.tsx import { useState, createContext, useContext, ReactNode } from "react"; interface INewExportRequestState { isCalculationLoadHw: boolean; } interface INewExportRequestStoreActions { getCalDraftHW(): void; getCalDraftSW(): void; } type NewExportRequestStoreType = INewExportRequestState & INewExportRequestStoreActions; const NewExportRequestContext = createContext<NewExportRequestStoreType | undefined>(undefined); // 状态共享Provider export const NewExportRequestProvider = ({ children }: { children: ReactNode }) => { const [isCalculationLoadHw, setCalculationLoadHw] = useState(false); const getCalDraftHW = (): void => { setCalculationLoadHw(true); setTimeout(() => { setCalculationLoadHw(false); }, 3000); } const getCalDraftSW = (): void => { setCalculationLoadHw(true); setTimeout(() => { setCalculationLoadHw(false); }, 3000); } return ( <NewExportRequestContext.Provider value={{ isCalculationLoadHw, getCalDraftHW, getCalDraftSW }} > {children} </NewExportRequestContext.Provider> ) } // 封装调用Hook export const useNewExportRequestStore = () => { const context = useContext(NewExportRequestContext); if (!context) throw new Error("useNewExportRequestStore需在NewExportRequestProvider内部使用"); return context; }
2. 外层包裹Provider
在所有需要用到该状态的组件的公共父组件(比如App.tsx)外层套Provider:
// App.tsx import { NewExportRequestProvider } from './Contract/NewExportRequestStore'; import NewCalculation from './NewCalculation'; import SwCalculation from './SwCalculation'; export default function App() { return ( <NewExportRequestProvider> <NewCalculation /> <SwCalculation /> </NewExportRequestProvider> ) }
3. 调整组件内的状态调用
所有组件直接从Hook返回值取状态和方法即可,不需要再嵌套state/actions层:
// NewChildSwCalculation.tsx 示例 import React from "react"; import { useNewExportRequestStore } from "./Contract/NewExportRequestStore"; const NewChildSwCalculation =() =>{ const { isCalculationLoadHw } = useNewExportRequestStore(); return( <div> Hello from the Child Sw Calculation <button disabled={isCalculationLoadHw}> Export Child Sw </button> </div> ); } export default NewChildSwCalculation;
其他组件按照同样的逻辑调整取值方式即可,所有组件都会共享同一份状态,子组件的按钮会随状态变化正常禁用。
内容的提问来源于stack exchange,提问作者Raida Adn
相关产品推荐
相关产品推荐

