Tengo dos componentes en el primer componente. Creé la función "onClick" con lógica difícil, la función "onClick" usa API y reductor, también usa otras funciones. Necesito usar la función "onClick" en el segundo componente, pero no sé cómo hacerlo mejor. ¿Puedes ayudarme por favor?
import React, { useEffect } from 'react'; import {Switch, Route, Link, Redirect} from 'react-router-dom'; import PageComponent_1 from '../page-component-1'; import PageComponent_2 from '../page-component-2'; const Application: React.FunctionComponent = () => { return ( <div> <div> <hr /> <nav> <ul> <li> <Link to="/PageComponent_1">PageComponent_1</Link> </li> <li> <Link to="/PageComponent_2">PageComponent_2</Link> </li> </ul> </nav> <hr /> <Switch> <Route exact path={ "/PageComponent_1" } component={ PageComponent_1 } /> <Route exact path={ "/PageComponent_2" } component={ PageComponent_2 } /> <Redirect to="/"/> </Switch> </div> </div> ); }; export default Application;primer componente
import React, {useState} from 'react'; type Props = { } type State = { field_1: string }; const PageComponent_1: React.FunctionComponent<Props> = () => { const [state, changeState] = useState<State>( { field_1: '', }, ); const onClick = (e:any, feldName:string) =>{ //here is difficult logic changeState((state) => ({ ...state, [feldName]: 'TEST' })); } return ( <div className=""> PageComponent_1 <div onClick={(e:any)=>onClick(e, 'field_1')}> ClickMe </div> </div> ); }; export default React.memo(PageComponent_1);segundo componente
import React, {useState} from 'react'; type Props = { } type State = { field_2: string }; const PageComponent_2: React.FunctionComponent<Props> = () => { const [state, changeState] = useState<State>( { field_2: '', }, ); return ( <div className=""> PageComponent_2 </div> ); }; export default React.memo(PageComponent_2);Puede crear la función fuera de cualquier componente, haciendo que acepte el tipo del objeto de estado como parámetro de tipo y la función de establecimiento de estado para usar ( changeState en su código) como parámetro:
const onClick = <StateType,>( e: any, fieldName: keyof StateType, changeState: React.Dispatch<React.SetStateAction<StateType>> ) => { //here is difficult logic changeState((state) => ({ ...state, [fieldName]: "TEST" })); };Así es como lo usa en su componente actual:
const PageComponent_1: React.FunctionComponent<Props> = () => { const [state, changeState] = useState<State>( { field_1: "", }, ); const onClickField1 = useCallback((e: any) => onClick(e, "field_1", changeState), []); return ( <div className=""> PageComponent_1 <div onClick={onClickField1}> ClickMe </div> </div> ); };Algunas claves allí:
onClick debe ser genérico para que el tipo de estado con el que trabaja provenga de donde se usa; ese es el parámetro de tipo StateType .fieldName es keyof StateType , por lo que podemos usarlo para establecer la propiedad de manera segura.changeState (más comúnmente llamado setState ) usa el tipo React React.Dispatch<React.SetStateAction<T>> donde T es un parámetro de tipo para el tipo del elemento de estado (en nuestro caso, StateType ). (Si alguna vez se pregunta acerca de los tipos de cosas como esa, en cualquier IDE decente puede pasar el mouse sobre el setter de estado, etc., y el IDE le mostrará el tipo).