簡體   English   中英

kickjs輸入元素在擊鍵后失去焦點

[英]reactjs input element loses focus after keystroke

所以我使用哈希來存儲動態創建的輸入值行的值,並且在輸入僅一個字符后我將注意力集中在我正在修改的輸入上。 我認為解決這個問題的方法可能是使用refs重新關注最后輸入的改變,但是我無法讓它工作,因為我無法弄清楚如何指定最后一次更改的元素。 關於如何解決這個問題的建議表示贊賞。

下面的代碼動態創建輸入框,並根據unitPriceValueHash查找其值。 每個變體都有一個id,id用作哈希的鍵。

我創建了一個codepen來嘗試重新創建問題,但我遇到的問題並沒有出現在代碼筆中。 在我的實際應用程序中,我在輸入框中按1,例如光標不再在輸入框上。

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

codepen和我的代碼之間的唯一區別似乎是輸入嵌套在表中。

嵌套在表中的輸入

  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);
  }

您共享的代碼存在一些問題。

  • 不要使用內聯函數。 每次渲染,再次創建函數,這意味着當react比較道具時,它看起來像函數不同(每次都是一個新的/不同的函數!)並且反應將重新渲染。
  • 不要修改狀態中存在的任何對象,而是創建新對象。 如果修改狀態中存在的對象,則實質上是說您不希望渲染具有一致性和可重現性。

我重新發布了原始代碼,突出了問題

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道具。

您尚未發布足夠的代碼供我們進一步調查。 如果您需要更多幫助,您應該構建一個我們可以運行和測試的最小可重復示例。

這個問題的解決方案讓我使用中間狀態來存儲更改時輸入字段的值,並在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}
      />
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM