首页 文章

kickjs输入元素在击键后失去焦点

提问于
浏览
2

所以我使用哈希来存储动态创建的输入值行的值,并且在输入仅一个字符后我将注意力集中在我正在修改的输入上 . 我认为解决这个问题的方法可能是使用refs重新关注最后输入的改变,但是我无法让它工作,因为我无法弄清楚如何指定最后一次更改的元素 . 关于如何解决这个问题的建议表示赞赏 .

下面的代码动态创建输入框,并根据unitPriceValueHash查找其值 . 每个变体都有一个id,id用作哈希的键 .

我创建了一个codepen来尝试重新创建问题,但我遇到的问题并没有出现在代码笔中 . 在我的实际应用程序中,我在输入框中按1,例如光标不再在输入框上 .

https://codepen.io/ByteSize/pen/oogLpE?editors=1011

codepen和我的代码之间的唯一区别似乎是输入嵌套在表中 .

Inputs nested in table

CreateItem(variant) {
    const unitPriceValueHash = this.props.unitPriceValueHash
    return { 
      variant_title: variant.variant_title,
      variant_price: variant.variant_price,
      unit_cost: <TextField 
                  type="number"
                  onChange={(event) => this.handleUnitPriceChange(variant.id, event)}
                  key={variant.id}
                  value={unitPriceValueHash[variant.id] || ''}
                 />
    };
  }

下面是修改哈希值的状态更改

handleUnitPriceChange (id, event) {
    const unitPriceValueHash = this.state.unitPriceValueHash
    unitPriceValueHash[id] = event
    console.log(unitPriceValueHash)
    this.setState({unitPriceValueHash: unitPriceValueHash});
    //this.updateVariantUnitCost(id, event);
  }

2 回答

  • 1

    您共享的代码存在一些问题 .

    • 不要使用内联函数 . 每次渲染,再次创建函数,这意味着当react比较道具时,它看起来像函数不同(每次都是一个新的/不同的函数!)并且反应将重新渲染 .

    • Don 't modify any objects which exist in the state, instead create a new object. If you modify an object that exists in the state, you'基本上说你不希望渲染具有一致性和可重复性 .

    我重新发布了原始代码并突出显示了问题

    CreateItem(variant) {
      const unitPriceValueHash = this.props.unitPriceValueHash
      return {
        variant_title: variant.variant_title,
        variant_price: variant.variant_price,
        unit_cost: <TextField
          type="number"
          onChange={(event) => this.handleUnitPriceChange(variant.id, event)}
          // ^^^^ - inline functions cause react to re-render every time, instead - create a component
          key={variant.id}
          value={unitPriceValueHash[variant.id] || ''}
        />
      };
    }
    
    handleUnitPriceChange(id, event) {
      const unitPriceValueHash = this.state.unitPriceValueHash
      unitPriceValueHash[id] = event
      // ^^^^ - please, please - don't do this. You can't mutate the state like this.
    
      // instead, do the following to create a new modified object without modifying the object in the state
      const unitPriceValueHash = Object.assign({}, this.state.unitPriceValueHash, { id: event });
      this.setState({ unitPriceValueHash: unitPriceValueHash });
    }
    

    关于内联函数,通常建议为此创建一个新组件,将该值作为prop . 这可能看起来像这样:

    class UnitCost extends PureComponent {
      static propTypes = {
        variantId: PropTypes.number,
        variantValue: PropTypes.object,
        onUnitPriceChange: PropTypes.func,
      }
      handleUnitPriceChange(e) {
        this.props.onUnitPriceChange(this.props.variantId, e)
      }
      render() {
        return (
          <TextField
            type="number"
            onChange={this.handleUnitPriceChange}
            value={this.props.variantValue || ''}
          />
        );
      }
    }
    
    CreateItem(variant) {
      const unitPriceValueHash = this.props.unitPriceValueHash
      return {
        variant_title: variant.variant_title,
        variant_price: variant.variant_price,
        unit_cost: (
          <UnitCost
            key={variant.id}
            variantId={variant.id}
            variantValue={unitPriceValueHash[variant.id]}
            onUnitPriceChange={this.handleUnitPriceChange}
          />
        ),
      };
    }
    

    关于你对焦点的关注,由于这个原因,反应通常会在更新后重新聚焦一个对象 .

    唯一的反应将失去焦点,如果它完全丢弃当前的DOM树并从头开始 . 如果它认为父对象已被替换而不是被修改,它将执行此操作 . 这可能是因为缺少 key 道具或已改变的 key 道具 .

    您尚未发布足够的代码供我们进一步调查 . 如果您需要更多帮助,您应该构建一个我们可以运行和测试的最小可重复示例 .

  • 0

    这个问题的解决方案让我使用中间状态来存储更改时输入字段的值,并在onBlur上提交AJAX请求

    class TextFieldWrapper extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          value: this.props.variantValue[this.props.variantId] || '',
        }
        this.handleUnitPriceChange = this.handleUnitPriceChange.bind(this)
        this.updateValue = this.updateValue.bind(this)
      }
      updateValue(value){
        this.setState({
          value: value,
        });
      }
      handleUnitPriceChange() {
        this.props.onUnitPriceChange(this.props.variantId, this.state.value);
      }
      render(){
        return (
          <TextField
            type="number"
            id={this.props.variantId}
            key={this.props.variantId}
            onChange={this.updateValue}
            onBlur={this.handleUnitPriceChange}
            value={this.state.value}
          />
        );
      }
    }
    

相关问题