2015-11-06 74 views
2

我在我的Meteor + React應用程序中有一個文本框。我想將其值同步到Mongo集合。但是,我不想在每次擊鍵後更新集合,只有當用戶停止鍵入幾秒時纔會更新集合。同步React狀態到使用去抖動的Meteor集合

文本框在我render()功能如下:

<input type="text" ref="answer" onChange={this.onChange} value={this.state.someValue} /> 

我的文本框的值存儲在this.state而不是this.data因爲this.data反映蒙戈集合,它可能尚未更新。

到目前爲止,所有這些工作。

問題:

如果另一個客戶端將更新集合,我想文本框來顯示更新值。爲此,我必須更新getMeteorData()函數中的this.state,但這是不允許的,並且出現錯誤:「在getMeteorData中調用setState可能導致無限循環」

現在我有一個解決方法,我手動更新componentDidMount()getMeteorData()中的文本框值,但它感覺有點ha and,我根本不喜歡它。

有沒有更好的方法來做到這一點?如果我保證我會成爲一個好孩子並表現得很好,我可以在getMeteorData()的內部強制更新嗎?

回答

1

我會擺脫getMeteorData在所有和轉到createContainer。數據流大部分時間都變得清晰簡單,包括這個特定的情況。在這裏。

首先,創建一個容器來獲取數據。

export default theContainer = createContainer(() => { 
    // Subscribe to the publication which publishes the data. 
    const subscription = Meteor.subscribe(...); 
    // Derive the data for the input box and form the props to pass down. 
    const props = { 
    answer: getAnswer(subscription) 
    }; 
    return props; 
}, theComponent); 

theContainer充當容器組件和由道具transferes所包含的數據的表象部件theComponent。請注意,createContainer的功能是相應的,這意味着該功能中被動數據源的更改會觸發重新運行並導致重新顯示theComponent

現在我們都是武裝的。由於Mongo集合中的數據(正好是Minimongo)由傳遞的道具同步,所以theComponent通過道具轉換知道同步。

export default class theComponent extends React.Component { 
    ... 

    componentWillReceiveProps(nextProps) { 
    if (this.props.answer !== nextProps.answer) { 
     this.setState({ 
     answer: nextProps.answer 
     }); 
    } 
    } 

    render() { 
    return <input value={this.state.answer} onChange={this.onChange} />; 
    } 
} 

雖然這種轉變發生,即將到來的值被更新的狀態,並且該控制部件將使得基於更新後的新的值的輸入。

另一方面,當用戶開始鍵入時,更改處理程序this.onChange會將用戶的輸入更新爲每個按鍵的狀態,因爲這是受控組件。但是,處理程序只有在預設時間已過時纔會更新Mongo集合(同樣是Minimongo)以保存數據傳輸。