2017-09-14 176 views
0

要求是:mobx反應觀察者組件不調用更新後呈現

切換到打開的行分量

高亮顯示選擇的行與青色的背景顏色

然而,當我點擊切換按鈕,該應用程序組件沒有重新渲染:(

// App.js 
import React, { Component } from 'react'; 
import {observable, action } from 'mobx'; 
import {observer} from 'mobx-react'; 

@observer class Rows extends Component { 
    rows() { 
    let { store } = this.props; 
    var rows = []; 
    for (var i = 4; i > 0; i--) { 
     rows.push(
     <div 
      style={i == store.selectedRow ? { backgroundColor: "cyan" } : null } 
      onClick={store.selectRow.bind(this, i)}> 
      { i } 
     </div> 
    ) 
    } 
    return rows; 
    } 
    render() { 
    return (<div>{this.rows()}</div>); 
    } 
} 

class Store { 
    constructor(props) { 
    this.selectRow = this.selectRow.bind(this) 
    this.toggleSelector = this.toggleSelector.bind(this) 
    } 
    @observable showSelector = false; 
    @observable selectedRow = 4; 
    @action selectRow(n) { 
    this.selectedVersion = n; 
    } 
    @action toggleSelector() { 
    this.showSelector = !this.showSelector; 
    } 
} 

//edit here 
const store = new Store(); 

@observer class App extends Component { 
    render() { 
    return (
     <div className="App"> 
     <button onClick={store.toggleSelector}>Toggle Selector</button> 
     { store.showSelector ? <Rows store={store}/> : null } 
     </div> 
    ); 
    } 
} 

export default App; 

編輯根據建議我已經提取了在組件外創建存儲。

+0

不要在App的渲染中創建一個新的'store'。改爲在班級之外創建它。 – Tholle

+0

不會改變任何東西。還是)感謝你的建議。 –

回答

1

更新:您可以嘗試使用@action.bound修飾符,並在構造函數中完全跳過bind(this)。我的猜測是手動綁定搞亂了綁定(沒有雙關語意圖)。

參見action.bound

動作裝飾/功能遵循正常規則在JavaScript結合。但是,Mobx 3引入了action.bound以自動將操作綁定到目標對象。請注意,與動作不同,(@)action.bound不帶名稱參數,因此名稱將始終基於動作綁定到的屬性名稱。因爲它的創建render()沒有被觀察到


您的商店。您需要創建商店並通過props或MobX的Provider將其傳遞給您的組件。

Provider是一個組件,可以將使用React的上下文機制的存儲(或其他東西)傳遞給子組件。如果你有不希望顯式傳遞多層組件的情況,這很有用。

注射可以用來拿起那些商店。它是一個更高階的組件,它接受一個字符串列表並使這些存儲可用於被包裝的組件。

+0

在組件外部定義它,即使它只是文件也不會改變我的輸出。 (還是)感謝你的建議。將嘗試提供者。 –

+0

看起來供應商對於這個解決方案是矯枉過正的。不過,我會發現它對我的實際項目非常有幫助,謝謝。 –

+0

如果您有興趣管理組件的內部狀態(即狀態不與其他組件共享),則可以簡單地使用「Component.setState」。 –

0

試試這個。

// App.js 
import React, { Component } from 'react'; 
import {observable, action } from 'mobx'; 
import {observer} from 'mobx-react'; 

@observer class Rows extends Component { 
    rows() { 
    let { store } = this.props; 
    var rows = []; 
    for (var i = 4; i > 0; i--) { 
     rows.push(
     <div 
      style={i == store.selectedRow ? { backgroundColor: "cyan" } : null } 
      onClick={store.selectRow.bind(this, i)}> 
      { i } 
     </div> 
    ) 
    } 
    return rows; 
    } 
    render() { 
    return (<div>{this.rows()}</div>); 
    } 
} 

class Store { 
    constructor(props) { 
    this.selectRow = this.selectRow.bind(this) 
    this.toggleSelector = this.toggleSelector.bind(this) 
    } 
    @observable showSelector = false; 
    @observable selectedRow = 4; 
    @action selectRow(n) { 
    this.selectedVersion = n; 
    } 
    @action toggleSelector() { 
    this.toggleSelector = !this.showSelector; 
    } 
} 

// defined outside 
const store = new Store(); 

@observer class App extends Component { 
    render() { 
    return (
     <div className="App"> 
     <button onClick={store.toggleSelector}>Toggle Selector</button> 
     { store.showSelector ? <Rows store={store}/> : null } 
     </div> 
    ); 
    } 
} 

export default App; 
+0

沒有。定義它外面,即使它只是文件不會改變我的輸出。 。 –