2016-06-24 2 views
2

У меня есть onBlur на текстовых полях ввода, которые автоматически сохраняют запись; Структура данных - это один документ, содержащий массив элементов. Если я сменил первый столбец элемента, а затем второй столбец быстро, сохранение первого столбца вызовет обновление, которое перезагрузит оба поля ввода.Как мне автосохранение с несколькими полями формы в React?

Как я могу предотвратить первое сохранение от перезагрузки всей строки, чтобы оба значения столбцов были сохранены?

Вот фрагмент кода (я mimiced сервер сохранить с setTimeout):

class Store { 
    static doc = {title: "test title", items: [{id: 1, one: "aa", two: "bbb"}, {id: 2, one: "yyy", two: "zzz"}]}; 

    static getDocument() { 
    return this.doc; 
    } 

    static saveDocument(doc) { 
     this.doc = doc; 
    } 

    static updateItemInDocument(item, callback) { 
     var foundIndex; 
     let updatedEntry = this.doc.items.find((s, index) => { 
     foundIndex = index; 
     return s.id === item.id; 
     }); 

     this.doc.items[foundIndex] = item; 
     setTimeout(() => { console.log("updated"); callback(); }, 1000); 
    } 
}; 

const Row = React.createClass({ 
    getInitialState() { 
    return {item: this.props.item}; 
    }, 

    update() { 
    let document = Store.getDocument(); 

    let updatedEntry = document.items.find((s) => { 
      return s.id === this.props.item.id; 
     }); 

    this.setState({ item: updatedEntry}); 
    }, 

    handleEdit() { 
    this.setState({item: { 
     id: this.props.item.id, 
     one: this.refs.one.value, 
     two: this.refs.two.value 
     } 
    }); 
    }, 

    handleSave() { 
    Store.updateItemInDocument(this.state.item, this.update); 
    }, 

    render() { 
    let item = this.state.item; 
    console.log(item); 
    return <tr> <p>Hello</p> 
     <input ref="one" type="text" onChange={this.handleEdit} onBlur={this.handleSave} value={item.one} /> 
     <input ref="two" type="text" onChange={this.handleEdit} onBlur={this.handleSave} value={item.two} /> 
     </tr>; 
    } 
}); 

const App = React.createClass({ 
    render() { 
    let rows = Store.getDocument().items.map((item, i) => { 
     return <Row key={i} item={item} />; 
    }); 

    return <table> 
     {rows} 
     </table>; 
    } 
}); 

ReactDOM.render(
    <App />, 
    document.getElementById("app") 
); 

У меня также есть код как codepen: http://codepen.io/tommychheng/pen/zBNxeW?editors=1010

+0

'item' всегда и только имеет свойства' one' и 'two'? Или может 'item' иметь больше или меньше этих свойств? – Ashitaka

+0

Элемент имеет фиксированное количество свойств (всего одно и два) и поля ввода. –

ответ

2

Проблема проистекает из того факта, что tabbing out of an input field fires both the onChange and onBlur handlers.

Может быть, я недоразумение вашего случая использования, но вот как я бы решить эту проблему:

const Row = React.createClass({ 
    getInitialState() { 
    return { item: this.props.item }; 
    }, 

    handleSave() { 
    let item = { 
     id: this.state.item.id, 
     one: this.refs.one.value, 
     two: this.refs.two.value 
    } 
    Store.updateItemInDocument(item); // Is it really necessary to use the callback here? 
    }, 

    render() { 
    let item = this.state.item; 
    return (
     <tr> 
     <p>Hello</p> 
     <input ref="one" type="text" onBlur={this.handleSave} defaultValue={item.one} /> 
     <input ref="two" type="text" onBlur={this.handleSave} defaultValue={item.two} /> 
     </tr> 
    ); 
    } 
}); 

Я переключился с помощью onChange обработчика using a defaultValue.

+0

Спасибо Ашитака! Я не знал о defaultValue. Он решает эту проблему обновления, перезаписывая значения после обновления. Моя проблема похожа на http://stackoverflow.com/questions/37946229/how-do-i-reset-the-defaultvalue-for-a-react-input/37946963, где комментатор предлагает использовать результаты '' defaultValue'' в «неконтролируемый компонент», который является плохой практикой. Есть ли у вас какие-либо мысли о «неконтролируемом компоненте»? –

+0

Я не думаю, что использование 'defaultValue' - это плохая практика. Это зависит от ваших случаев использования. В этом случае, я думаю, использование 'defaultValue' совершенно допустимо. – Ashitaka

 Смежные вопросы

  • Нет связанных вопросов^_^