Soy nuevo en reaccionar y tengo una entrada personalizada en la que manejo el valor y el controlador de entrada a través de un gancho personalizado, pero me gustaría obtener el valor y el controlador de entrada para el componente principal usando la entrada personalizada, pero estoy atascado en cómo lograr esto. He escrito el siguiente código.
En el gancho personalizado
import {useReducer} from "react"; const INITAL_STATE = {value:'',valid:false,pristine:true, error:''} const REDUCER_ACTIONS = { input:"INPUT", blur:"BLUR"} const reducer = (state,action)=>{ if (action.type === REDUCER_ACTIONS.input){ return {...state, value: action.value} } if (action.type === REDUCER_ACTIONS.blur){ return {...state, pristine: false} } return INITAL_STATE; } const useForm = () => { const [inputState, dispatch] = useReducer(reducer,INITAL_STATE) const onBlurHandler = (event) => { dispatch({type:REDUCER_ACTIONS.blur}); } const onInputHandler = (event) => { dispatch({type:REDUCER_ACTIONS.input,value:event.target.value}) } return { ...inputState, onBlurHandler, onInputHandler } }; export default useForm;Y para mi entrada personalizada tengo
import useForm from "../../hooks/use-form"; const CustomInput = (props) => { const {value, onInputHandler, onBlurHandler} = useForm(); //uses custom hook return <> <label htmlFor={props.id}>{props.label}</label> <input value={value} onBlur={onBlurHandler} onInput={onInputHandler} {...props} /> </> } export default CustomInput;La entrada personalizada anterior tiene onInput y onBlur apuntando a los ganchos personalizados, ya que quiero reutilizar la funcionalidad en otros tipos de entrada, como los selectores de fecha y selección, sin tener que duplicarlos.
En mi componente principal, simplemente estoy llamando a la entrada personalizada como
function App() { return ( <div className="container"> <CustomInput onInputHandler={} label="First name"/> </div> ); } export default App;Me gustaría pasar el onInputHandler y el valor como accesorios al componente principal desde la entrada personalizada, pero no sé cómo hacerlo. ¿Cómo procedo?
Cuando dice que necesita pasar el valor, supongo que quería pasar el valor inicial de la entrada a CustomInput. Para lograr eso puedes pasar otro prop.
initialValue a CustomInput <CustomInput initialValue={"abc"} label="First name" />CustomInput , pase la propiedad initialValue a useForm hook como argumento. const { value, onInputHandler, onBlurHandler } = useForm(props.initialValue);initialValue como el value en estado inicial en useForm . const useForm = (initialValue) => { const [inputState, dispatch] = useReducer(reducer, { ...INITAL_STATE, value: initialValue }); ... ... } Para pasar onInputHandler como accesorio, puede verificar si onInputHandler está disponible como accesorio y llamarlo junto con onInputHandler proveniente de useForm .
event como argumento. export default function App() { const onInputHandler = (e) => { console.log(e); }; return ( <div className="App"> <CustomInput ... onInputHandler={onInputHandler} label="First name" /> </div> ); }CustomInput , cambie el controlador onInput como se muestra a continuación. Puede cambiar la lógica según sus necesidades (llamé a onInputHandler en useForm y prop ). <input value={value} onBlur={onBlurHandler} onInput={(e) => { props.onInputHandler && props.onInputHandler(e); onInputHandler(e); }} {...props} />Mi enfoque para esto será simplemente llamar a onInputHandler() desde hooks y onInputHandler() desde los props recibidos de Parent y enviar e.target.value como accesorio a estas funciones.
const CustomInput = (props) => { const { value, onInputHandler, onBlurHandler } = useForm(); //uses custom hook console.log(value); const handleInputChange = (e: any) => { onInputHandler(e); props.onInputHandler(e.target.value); }; return ( <> <label htmlFor={props.id}>{props.label}</label> <input value={value} onBlur={onBlurHandler} onInput={(e) => { handleInputChange(e); }} {...props} /> </> ); }; export default CustomInput; Y en el componente principal podemos recibirlos como props devueltos por esa función y usarlos de acuerdo con nuestros requisitos.
function App() { return ( <div className="container"> <CustomInput label="name" onInputHandler={(value: string) => console.log("App",value)} /> </div> ); } export default App;enlace de la caja de arena: https://codesandbox.io/s/nifty-lamport-2czb8?file=/src/App.tsx:228-339