Reactjs 在React中使用HOC创建受控输入

Reactjs 在React中使用HOC创建受控输入,reactjs,higher-order-components,Reactjs,Higher Order Components,我试图创建一个HOC来呈现受控输入,但我所有的努力都会导致输入在onChange之后失去焦点。我认为这是键的一个基本问题,但摆弄键似乎没有帮助,我花了几个小时在各种“HOC with inputs”博客/示例中,似乎找不到任何来自父节点状态的受控输入。我做错了什么?提前谢谢 编辑:HOC的目标是获取验证钩子的返回。在添加了额外的代码之后,我为这个问题创建了一个解决方案,希望能有所帮助 type WrapperProps = { name: string; labe

我试图创建一个HOC来呈现受控输入,但我所有的努力都会导致输入在onChange之后失去焦点。我认为这是键的一个基本问题,但摆弄键似乎没有帮助,我花了几个小时在各种“HOC with inputs”博客/示例中,似乎找不到任何来自父节点状态的受控输入。我做错了什么?提前谢谢

编辑:HOC的目标是获取验证钩子的返回。在添加了额外的代码之后,我为这个问题创建了一个解决方案,希望能有所帮助

    type WrapperProps = {
      name: string;
      label: string;
      onChange?: (event: any) => void;
      state: any;
    }
    
    export const InputWrapper = (v: ValidationObject) => {
      const Wrapper: FC<WrapperProps> = (props) => {
        const { label, onChange, name, state } = props;
    
        const getPattern = (value: any) => {
          return v.getFieldValid(name)
            ? `${value}`
            : `${randomString()}`
        };

        const modifiedProps = { 
          name,
          onBlur: () => v.validate(name, prop(name, state), state),
          onChange,
          pattern: getPattern(state[name]),
          value: state[name],
        };

        return (
          <React.Fragment>
            <label htmlFor={name}>{label}</label>
            <input key={name} id={name} {...modifiedProps} />
            <p style={{ color: 'red' }}>{v.getError(name)}</p>
          </React.Fragment>
        );
      }
 
     return Wrapper;
    }
下面是一个正在使用的示例:

    import React, { useState } from 'react';
    import {BasicInputValidation} from 'examples/basicInput.validation';
    import {InputWrapper} from 'withValidationComponent';
    import { curry } from 'ramda';
    
    function App() {
      const [state, setState] = useState<{name: string}>({ name: '' });
    
      const onChange = curry((name: string, event: any) => {
        const data = { [name]: event.target.value }
        setState({ ...state, ...data });
      })

      const v = BasicInputValidation();
      const HOC = InputWrapper(v);
    
      return (
        <>
          <HOC 
            name="name"
            label="Name"
            onChange={onChange('name')}
            state={state}
          />
        </>
      );
    }
    
    export default App;
import React,{useState}来自“React”;
从“examples/basicInput.validation”导入{BasicInputValidation};
从“withValidationComponent”导入{InputWrapper};
从“拉姆达”输入{curry};
函数App(){
const[state,setState]=useState({name:'});
const onChange=curry((名称:string,事件:any)=>{
常量数据={[name]:event.target.value}
setState({…state,…data});
})
常数v=基本输入验证();
const HOC=输入包装器(v);
返回(
);
}
导出默认应用程序;

每个渲染似乎都会导致原始的
InputWrapper
组件卸载。在这一点上,这是因为这个代码
consthoc=InputWrapper({})-每次在父级上进行渲染时,都会生成一个新的包装。这在我的实验中是显而易见的:

export const InputWrapper = (v) => {
  const Wrapper = (props) => {
    const { label, onChange, name, state } = props;

    useEffect(() => {
      return () => {
        console.log("unmounting"); // cleanup got invoked everytime I typed in the input
      };
    }, []);
错误的代码沙盒:


为了解决这个问题,在实现端(即在应用程序组件上),我将包装器实例移到了函数外部

import React, { useState } from "react";
import {BasicInputValidation} from 'examples/basicInput.validation';
import {InputWrapper} from 'withValidationComponent';
import { curry } from 'ramda';
const HOC = InputWrapper({}); // <-- moved this here

function App() {
  ...
import React,{useState}来自“React”;
从“examples/basicInput.validation”导入{BasicInputValidation};
从“withValidationComponent”导入{InputWrapper};
从“拉姆达”输入{curry};

const HOC=InputWrapper({});// 每个渲染似乎都会导致原始的
InputWrapper
组件卸载。在这一点上,这是因为这个代码
consthoc=InputWrapper({})-每次在父级上进行渲染时,都会生成一个新的包装。这在我的实验中是显而易见的:

export const InputWrapper = (v) => {
  const Wrapper = (props) => {
    const { label, onChange, name, state } = props;

    useEffect(() => {
      return () => {
        console.log("unmounting"); // cleanup got invoked everytime I typed in the input
      };
    }, []);
错误的代码沙盒:


为了解决这个问题,在实现端(即在应用程序组件上),我将包装器实例移到了函数外部

import React, { useState } from "react";
import {BasicInputValidation} from 'examples/basicInput.validation';
import {InputWrapper} from 'withValidationComponent';
import { curry } from 'ramda';
const HOC = InputWrapper({}); // <-- moved this here

function App() {
  ...
import React,{useState}来自“React”;
从“examples/basicInput.validation”导入{BasicInputValidation};
从“withValidationComponent”导入{InputWrapper};
从“拉姆达”输入{curry};

const HOC=InputWrapper({});//请给出您创建的HOC的一些用法示例。观众将有一个更容易的时间以这种方式再现问题。请阅读并给出您创建的HOC的一些用法示例。观众将有一个更容易的时间以这种方式再现问题。请读有趣的,我现在明白了。然而,唯一的问题是,我希望为HOC提供的参数是一个钩子的输出,该钩子包含管理验证状态的所有对象和函数,我无法在函数外部呈现钩子。我会给我的例子添加更多的代码,但是我可能需要考虑一个不同的体系结构。也许…我试着记下你返回的组件-看,可能会给你一些提示,我现在明白了。然而,唯一的问题是,我希望为HOC提供的参数是一个钩子的输出,该钩子包含管理验证状态的所有对象和函数,我无法在函数外部呈现钩子。我会给我的例子添加更多的代码,但是我可能需要考虑一个不同的体系结构。也许…我试着记下你返回的组件-看,可能会给你一些线索
import React, { useState } from "react";
import {BasicInputValidation} from 'examples/basicInput.validation';
import {InputWrapper} from 'withValidationComponent';
import { curry } from 'ramda';
const HOC = InputWrapper({}); // <-- moved this here

function App() {
  ...