tengo la siguiente situacion:
Lo que estoy haciendo ahora es esto: tengo un componente que acepta una clave como accesorios y, a partir de un mapa predefinido, sabré el componente que quiero representar (usando React.lazy()), título modal, y texto del botón de acción. Funciona, pero de esta manera tengo que usar la función de mi hijo cuando se hace clic en el botón de acción (por ejemplo, con el uso de ref), pero quiero evitar esto, ya que no es la forma de reaccionar.
export function MyModal(props: MyModalProps) { const {onClose, isOpen, key} = props; // custom hook that gives me the details for the render (including the component with React.lazy) const { title, subtitle, Component, actionText, changeKey, nextKey } = useModalRenderDetails(key); const handleModalHide = (event) => { onClose(); }; return ( <Modal modalTitle={title} modalSubtitle={subtitle} mainActionLabel={actionText} secondaryActionLabel={'Skip'} open={isOpen} onHide={event => handleModalHide(event)} onMainAction={childHandlerFunctionFromRef} onSecondaryAction={() => changeKey(nextKey)} > <React.Suspense fallback={<div>LOADING</div>}> <Component/> </React.Suspense> </Modal> ); }¿alguien puede proporcionar una mejor solución para esta situación? Siéntase libre de sugerir cambios de diseño si es necesario
Esto parece un buen uso de un context .
Considere colocar el código a continuación en un archivo separado y exportar solo los elementos necesarios.
En primer lugar, defina un contexto:
const ConnectionContext = createContext();Luego cree un proveedor personalizado para envolver las funciones que necesita
const ConnectionContextProvider = ({ children }) => { const action = useRef(null); const setAction = (action) => { action.current = action; } const removeAction = () => { action.current = null; } const dispatchAction = () => { action.current && action.current() } return ( <ConnectionContext.Provider value={{ setAction, removeAction, dispatchAction, }} > {children} </ConnectionContext.Provider> ); } Luego envuelva el useContext (este paso es opcional)
const useConnectionContext = () => { const context = useContext(context); return context; }en el padre:
const MyModal = () => { const { dispatchAction } = useConnectionContext() // ... return ( <Modal // ... onMainAction={dispatchAction} > // ... </Modal> ) }en el niño:
const Child = () => { const { setAction, removeAction } = useConnectionContext() useEffect(() => { setAction(() => { // the action you want to run }) return () => removeAction() }, []) }Tenga en cuenta que todo el código en esta respuesta no está probado.