Javascript 包装一个组件意味着它失去了对rerender的关注

Javascript 包装一个组件意味着它失去了对rerender的关注,javascript,reactjs,Javascript,Reactjs,我有很长的反应时间。在此之前,它有一系列被定义为这样的组件: <input type='text' value={this.state.form.nameOfFormField} onChange={this.updateForm('nameOfFormField')} /> const SpecialInputBuilder = (form, onChange) => ({ field, ..props }) => ( <input ty

我有很长的反应时间。在此之前,它有一系列被定义为这样的组件:

<input
  type='text'
  value={this.state.form.nameOfFormField}
  onChange={this.updateForm('nameOfFormField')} />
const SpecialInputBuilder = (form, onChange) => ({ field, ..props }) => (
  <input
    type='text'
    value={form[field]}
    onChange={onChange(field)}
    {...props} />
)
现在,我可以这样定义渲染期间的输入:

const SpecialInput = SpecialInputBuilder(this.state.form, this.updateForm)
并在组件中使用它,如下所示:

<SpecialInput field='nameOfFormField' />


显然,这要简洁得多。但这也意味着每次输入到输入字段时(即调用
updateForm
时),输入字段都会降低焦点,因为每次调用
render
函数时都会定义
SpecialInput
。为每个元素定义一个
,似乎根本不能缓解问题。在仍然使用这个更简单的组件的情况下,如何解决这个问题?有中间立场吗?

主要问题是,
onChange
调用在呈现后立即执行,而不是在输入更改时调用函数的引用

// this executes immediately
onChange={onChange(field)}

// this is a reference to the function with a prop prepended
onChange={onChange.bind(this,field)}

我有一个类似的方法,但最终改变了这个方法

(1)输入打字机子组件:

import React, { Component } from 'react';

class FreeTextField extends Component {
  inputValueFn(e) {
    this.props.userInput(this.props.responseObject, e.target.value);
  }
  render() {
    return (
      <div className="input-group">
            <label>{this.props.buttonText ? this.props.buttonText : "Firstname"}</label>
            <input type={this.props.type} placeholder="" className="form-control" defaultValue={this.props.defaultValue} onChange={this.inputValueFn.bind(this)} />
      </div>
    );
  }
}

export default FreeTextField;
import React,{Component}来自'React';
类FreeTextField扩展组件{
输入值Fn(e){
this.props.userInput(this.props.responseObject,e.target.value);
}
render(){
返回(
{this.props.buttonText?this.props.buttonText:“Firstname”}
);
}
}
导出默认的FreeTextField;
(2)从父组件,您可以通过道具指定所有相关的子属性

// import
import FreeTextField from './pathTo/FreeTextField';

// Initial state
this.state = {
responseObject: {}
}

// onChange it updates the responseObject
    userInput(fieldKey,value) {
        let responseObject = this.state.responseObject;
        responseObject[fieldKey] = value;
        this.setState({responseObject:responseObject});
    }

// component render()
<FreeTextField 
buttonText="First Name" 
type="text" 
formObjectKey="first_name" 
userInput{this.userInput.bind(this)} />
//导入
从“/pathTo/FreeTextField”导入FreeTextField;
//初始状态
此.state={
响应对象:{}
}
//一旦更改,它将更新responseObject
用户输入(字段键、值){
让responseObject=this.state.responseObject;
响应对象[字段键]=值;
this.setState({responseObject:responseObject});
}
//组件渲染()

为什么不将输入生成器更改为一个组件呢

const SpecialInput = (props) => {
  return (
    <input
      value={props.form[props.field]}
      {...props}
      type={props.type || 'text'}
      onChange={() => props.onChange(props.field)} 
    />
  )
}
const SpecialInput=(道具)=>{
返回(
props.onChange(props.field)}
/>
)
}
用同样的方法

<SpecialInput field='nameOfFormField' onChange={this.updateForm} form={this.state.form} />


我能想到的唯一方法是将输入定义为react类上的项。aka in component willmount您可以创建一个
this.specialInput=SpecialInputBuilder(this.state.form,this.updateForm)
,然后在渲染中使用已定义的输入。我的问题是它是如何工作的?他以前的“工作”代码有
onChange={this.updateForm('nameOfFormField')}
,无论如何它都不应该按原样工作。尽管如此,我认为这不是他正在报道的问题。这是因为在每个渲染周期上都会创建一个新的输入对象,该对象会重置光标以及与其相关的所有内容
onChange
在我的代码中返回一个函数,该函数处理
事件
对象,即
(字段)=>(事件)=>{}
。抱歉,我在原始问题中没有说清楚-我现在更新。如果不绑定它或生成空函数,然后将参数传递给您,您仍然不能使用params调用它。@Brand您需要一个
bind
this
作为
=>onChange.bind(这个,字段,事件)上的第一个参数
updateForm
在元素的构造函数中绑定。我不确定您认为这里的问题是什么-打开包装时,
输入
元素工作正常,也使用了
onChange={this.updateForm('nameOfFormField')}
。如果您这样定义
特殊输入
,然后,
表单
从未作为我能看到的道具传递?@KyleFahringer抱歉,我忘了将其添加到使用该组件的渲染部分。更新。不管怎样,以这种方式使用组件的目的被打破了——我仍然必须在每次使用
SpecialInput
道具时定义
form
onChange
道具,这正是我试图避免的。虽然这在技术上可以解决问题,但基本上相当于在任何地方都使用
输入
元素。@KyleFahringer,这是一种反应式的做事方式。使用您已经定义的内容的唯一其他方法是我在评论中描述的。您必须在willMount函数中定义这些输入,并在组件的整个生命周期中使用对这些输入的引用。如果你愿意,我可以试着在我的答案中写一个模拟答案