2017-03-06 75 views
3

我正在用全局狀態和redux中的可重用組件的概念掙扎。帶React Redux的通用組件

比方說,我有一個組件是一個文件選擇器,我想在我的應用程序狀態中的多個位置使用它。創建動作/縮減器會導致大量的膨脹,因爲我必須用動態後綴和其他奇怪的東西來處理狀態,這並不是真正意義上的智能方式。

這些事情的普遍共識是什麼?我只能看到兩種解決方案:

  • 使文件選擇器組件具有本地狀態(this.setState/this.getState

  • 使文件選擇器是全局狀態的一部分,但在它自己獨特的減速,我可以從組件的操作完成後讀取嗎?

任何想法/最佳實踐?謝謝。

更新:爲了澄清我所描述的文件選擇不是一個簡單的組件,它的工作原理完全在客戶端,但必須從服務器獲取數據,提供分頁以及過濾等等。這就是爲什麼我」 d也喜歡重用大部分的客戶/服務器交互。顯示這個組件的視圖當然是愚蠢的,只顯示來自狀態的值 - 但是如何在應用程序的多個位置重用動作/縮減器?

回答

3

讓您的reducer處理組件狀態的多個實例。只需爲應用中出現的FileBrowser組件的每個實例定義一些「唯一」ID,並將此當前狀態包含在具有此uniqueIds作爲鍵的對象中,並將舊複雜狀態視爲值。

這是我多次使用的技巧。如果所有FileBrowser在編譯時已知,您甚至可以在運行應用程序之前設置初始狀態。如果您需要支持「動態」實例,只需創建一個用於初始化給定ID的狀態的Action。

你沒有提供任何代碼,但這裏有一個可重複使用的Todo減速一個人爲的例子:

function todos(state={}, action){ 
    switch(action.type){ 
    case 'ADD_TODO': 
     const id = action.todoListId 
     return { 
     ...state, 
     [id]: { 
      ...state[id], 
      todos: [ ...state[id].todos, action.payload ] 
     } 
     } 
     // ... 
    } 
} 
+0

是的,這是我們目前如何解決它..只是尋找一個更好的方式,因爲它有很多移動部件和動態調度,我想避免..(行動需要攜帶[ID]周圍所以你把它們包裝在部分應用的函數等中。) – Tigraine

+0

你也可以用它自己的邏輯+數據使它成爲一個獨立的組件,並使它不在你的Redux存儲中,例如使用'recompose'來處理它通過reducer的內部狀態功能。但是我的經驗是,最終別的人會想知道一些事情! :) – CharlieBrown

1

通常,根據經驗法則,您使用redux store來管理應用程序中的數據,即存儲從服務器獲取的項目以及本地react state中的UI行爲,例如您的案例中的文件上載。我會做一個純粹的反應組件來管理文件上傳,然後使用redux-form來管理特定的表單。

這是我在我的項目使用的組件

import React, {Component, PropTypes} from 'react'; 
import Button from 'components/Button'; 

class FileButton extends Component { 
    static propTypes = { 
    accept: PropTypes.string, 
    children: PropTypes.any, 
    onChange: PropTypes.func.isRequired 
    }; 

    render() { 
    const {accept, children, onChange} = this.props; 
    return <Button {...this.props} onClick={() => this.file.click()}> 
     <input 
     ref={el => this.file = $(el)} 
     type="file" 
     accept={accept} 
     style={{display: 'none'}} 
     onChange={onChange} 
     /> 
     {children} 
    </Button>; 
    } 
} 

export default FileButton; 
1

我們得出的結論是可重複使用的組件必須分爲兩種類型的例子:

  • 啞組件,即組件只接收道具並僅通過道具回調引發「行動」。這些組件具有最小的內部狀態或根本沒有。這些是可重用組件中最常見的,並且您的文件選擇器可能屬於這種情況。樣式化的文本輸入或自定義列表也是很好的例子。

  • 連接的組件提供自己的操作和reducer。這些組件在應用程序中有自己的生活,並且與其他應用程序相比是獨立的。一個典型的例子是當應用程序嚴重失敗時,顯示在所有其他應用程序之上的「最高錯誤消息框」。在這種情況下,應用程序會觸發一個「錯誤操作」,並將相應的消息作爲有效負載進行觸發,並在隨後的重新呈現中,消息框顯示在其餘的頂部。

+0

在我的情況下,文件選擇是一個相當複雜的組件,需要從服務器獲取數據,過濾器這些也提供分頁等pp。這就是爲什麼它只是一個愚蠢的組件導致動作/減速器方面的重複(當然,這些視圖是轉儲),但它封裝的邏輯是相當複雜的。 – Tigraine