2017-11-25 268 views
2

我一直在努力圍繞這個概念包紮我的頭,但沒有運氣。 官方的React教程非常好,但對我來說它太複雜,只是有點太難。Redux如何更改React中的UI?

我想了解Redux和迄今爲止我可以創建動作,reducer,我可以調度一個動作,然後看看它在調度它後如何更改存儲狀態。我也設法瞭解react-redux的connect,它工作的非常好,我可以在我的應用程序的任何地方觸發分派。所以我想我幾乎已經明白了。幾乎,因爲這裏是房間裏的大象 - 我發出行動,我看到了Redux狀態的變化,但是我該如何更改UI?

比如我在初始狀態text對象與價值Initial text而一旦按鈕被點擊我想文字更改爲Clicked text,並在UI的地方顯示的文字(讓我們的按鈕說)。

如何「訪問」React中的Redux狀態,以及如何動態改變它?

這似乎是非常簡單的沒有反應,例如::https://jsfiddle.net/loktar/v1kvcjbu/ - render函數處理一切,我明白這裏發生的一切。

但是另一方面,官方React + Redux教程中的「todo」看起來像這樣:https://redux.js.org/docs/basics/ExampleTodoList.html,它非常複雜,我不知道在哪裏看。

Add Todo按鈕提交表單發送dispatch(addTodo(input.value))動作。動作本身不做任何事情只是增加ID並將文本傳遞給商店,而reducer只是返回新的狀態。那麼如何在頁面上呈現待辦事項?哪裏?我迷失在這一點上。也許有更簡單的教程,我很想有一個單一的Redux教程它仍然可以複雜的多層組件:(

我懷疑在TodoList.js中發生的奇蹟,因爲他們映射的東西有,但我仍然不知道哪裏來的待辦事項從那裏,它與終極版做什麼(有沒有簡單的減速/動作/在該文件中派遣)。

感謝您的幫助!

+1

看看'mapStateToProps'函數,這是你失蹤的最後一塊。它會從redux狀態更新組件的道具,從而在狀態更改時觸發重新渲染。 – xDreamCoding

回答

3

我覺得你的困惑是那部分reducer compositionselectors

讓我們從相反的UI開始,以相反的順序來看它。

在連接部件containers/VisibleTodoList.js它從「狀態」(的redux全局存儲對象)的內部mapStateToProps得到todos,而使其通過的getVisibleTodos方法。
可以稱之爲一個選擇器,因爲它選擇並僅返回其接收到的數據的一部分:

import { connect } from 'react-redux' 
import { toggleTodo } from '../actions' 
import TodoList from '../components/TodoList' 

const getVisibleTodos = (todos, filter) => { 
    switch (filter) { 
    case 'SHOW_COMPLETED': 
     return todos.filter(t => t.completed) 
    case 'SHOW_ACTIVE': 
     return todos.filter(t => !t.completed) 
    case 'SHOW_ALL': 
    default: 
     return todos 
    } 
} 

const mapStateToProps = state => { 
    return { 
    todos: getVisibleTodos(state.todos, state.visibilityFilter) 
    } 
} 

const mapDispatchToProps = dispatch => { 
    return { 
    onTodoClick: id => { 
     dispatch(toggleTodo(id)) 
    } 
    } 
} 

const VisibleTodoList = connect(
    mapStateToProps, 
    mapDispatchToProps 
)(TodoList) 

export default VisibleTodoList 

state(Redux的商店)傳遞給mapStateToProps從根減速器reducers/index.js來到和實際上是一個單減速器(對象),其經由combineReducers效用的redux代表所有其他減速器的組合:

import { combineReducers } from 'redux' 
    import todos from './todos' 
    import visibilityFilter from './visibilityFilter' 

    const todoApp = combineReducers({ 
    todos, 
    visibilityFilter 
    }) 

    export default todoApp 

正如可以看到的,todos減速機在那裏。所以這就是爲什麼在mapStateToProps裏我們把它叫做這個state.todos

這裏是reducers/todos.js

const todos = (state = [], action) => { 
    switch (action.type) { 
    case 'ADD_TODO': 
     return [ 
     ...state, 
     { 
      id: action.id, 
      text: action.text, 
      completed: false 
     } 
     ] 
    case 'TOGGLE_TODO': 
     return state.map(todo => 
     (todo.id === action.id) 
      ? {...todo, completed: !todo.completed} 
      : todo 
    ) 
    default: 
     return state 
    } 
} 

export default todos 

'ADD_TODO'類型的每個動作會返回一個新的狀態,新的todo

case 'ADD_TODO': 
      return [ 
      ...state, 
      { 
       id: action.id, 
       text: action.text, 
       completed: false 
      } 
      ] 

它裏面actions/index.js這個行動的創建者:

let nextTodoId = 0 
export const addTodo = text => { 
    return { 
    type: 'ADD_TODO', 
    id: nextTodoId++, 
    text 
    } 
} 

So h ere是redux的全部流程(我省略了調用動作的按鈕,因爲我認爲這對你來說是顯而易見的部分)。
好,幾乎全流,沒有這種可能發生而不Provider HOC封裝了App並注入實體店就在index.js

import React from 'react' 
import { render } from 'react-dom' 
import { Provider } from 'react-redux' 
import { createStore } from 'redux' 
import todoApp from './reducers' 
import App from './components/App' 

let store = createStore(todoApp) 

render(
    <Provider store={store}> 
    <App /> 
    </Provider>, 
    document.getElementById('root') 
) 

現在,當reduxstate變化,mapStateToProps通話被調用,將返回新映射的propsconnect將通過這些新的props,這將觸發一個新的render調用(實際上整個反應生命週期流)到連接的組件。
這種方式將使用來自商店的新數據重新呈現用戶界面。

+1

以上是否有助於澄清混淆? –

1

連接時通常用於連接Reaction組件和Redux狀態.connect是一個高階組件,使用connect函數的組件封裝在其中,方法簽名爲 connect([ma pStateToProps],[mapDispatchToProps],[mergeProps],[options]) mapStateToProps可以訪問redux狀態,並且mapDispathToProps可以訪問store.dispatch。所有的道具都被合併並作爲道具傳遞給底層組件。 Redux只有單一的真相狀態。 store作爲道具傳遞給Provider組件有一個名爲store.getState()的方法。

因此,請記住一點,反應組件是數據驅動的。數據派生UI。只有當狀態改變或道具已被修改時,React組件纔會重新渲染。你可以在任何兩個部分進行更改,組件會經歷各種生命週期方法。