2016-09-15 64 views
0

晚上好,準備好大量代碼。Redux調度程序不工作

我正在學習如何使用Redux與React來努力在組件之間共享狀態,並且我一直在嘗試使導航欄根據您點擊的div來改變顏色。在較高的水平我想終極版,讓我做到以下幾點...

<Navigation> 
    <NavEndpt /> <-- click an endpoint and you set this.props.active to true 
    <NavEndpt /> <-- resets the rest and set this.props.active to false 
</Navigation> 

所以基本上成分改變顏色,當你點擊它們,這是真的很難做陣營我是來了解一下。根據我正在觀看的教程,我有我的調度員正確連線,並且我仍然沒有成功更改狀態。也許我不完全理解Redux,但我一定會感謝一些幫助。我將按照最適合理解我的問題的順序提供片段,也許您可​​以發現我出錯的位置。

client.js附加到index.html沒什麼特別的。

import React from "react"; 
import ReactDOM from "react-dom"; 
import { Provider } from "react-redux"; 

import Layout from "./components/Layout" 
import store from "./store" 

const app = document.getElementById("app"); 

ReactDOM.render(<Provider store={store}><Layout /></Provider>, app); 

store.js

import { applyMiddleware, createStore } from "redux"; 

import reducer from "./reducers/mainReducer" 

export default createStore(reducer) 

這裏是navReducer.js,設置初始狀態:

export default function reducer(state = { 
    about: { 
    id: "about", 
    title: "Who I am", 
    active: false 
    }, 
    projects: { 
    id: "projects", 
    title: "What I do", 
    active: false 
    } 

}, action) { 

    switch (action.type) { 
    case "CLICK": { 
     return {...state, active: true } 
     break 
    } 
    } 

    return state 
} 

這裏是navActions.js有一個動作......

export function activeBox(){ 
    return{ 
    type: "CLICK", 
    } 
} 

以下是使用上述片段的組件。一個說明,我沒有收到控制檯或終端的任何錯誤,這讓我相信我的問題只是一個文件的不好的路徑。

Layout.js

import React from "react"; 

import Nav from "./views/Nav" 

import { connect } from "react-redux"; 

@connect((store) => { 
    return{ 

     about: store.navControls.about, 
     projects: store.navControls.projects 

    }; 
}) 
export default class Layout extends React.Component { 


    render(){ 


    return(
     <div id="wrapper"> 
     <Nav about={this.props.about} projects={this.props.projects} dispatch={this.props.dispatch} /> 
     <div id="content"></div> 
     </div> 
    ) 

    } 
} 

Nav.js(在Layout功能)

import React from "react"; 

import NavEndpt from "./NavEndpt" 

const Nav = React.createClass({ 


    render(){ 

    let about = this.props.about; 
    let projects = this.props.projects; 


    return(
     <div id="navigation"> 
     <NavEndpt data={about} dispatch={this.props.dispatch} /> 
     <NavEndpt data={projects} dispatch={this.props.dispatch} /> 
     </div> 
    ) 
    } 
}) 


export default Nav; 

最後NavEndpt.js

import React from "react"; 

import { activeBox } from "../../actions/navActions.js" 

const NavEndpt = React.createClass({ 
    handleClick(){ 
    let data = this.props.data; 
    console.log("clicked " + data.active) 

    this.props.dispatch(activeBox()); // this does nothing, checking out React in the chrome dev tools shows no change to about.active or projects.active 
    }, 

    styleUpdate(){ 
    let data = this.props.data; 

    if (data.active === false){ 
     return{ 
     background: "violet" 
     } 
    } else if (data.active === true){ 
     return { 
     background: "yellow" 
     } 
    } 
    }, 

    render(){ 
    let data = this.props.data; 
    return(

     <div className="navButton" onClick={this.handleClick} style={this.styleUpdate()}> 
     <span>{data.title}</span> 
     </div> 

    ) 
    } 
}) 

export default NavEndpt; 

提前堆棧溢出社區謝謝,我期待着您的見解,因爲我一直試圖讓這一天工作。

歡呼

+0

您應該使用React Dev Tools,而不僅僅是Chrome開發工具。可以從這裏安裝:https://facebook.github.io/react/blog/2014/01/02/react-chrome-developer-tools.html 我懷疑你會看到你的狀態實際上更新。它變成'{about:...,projects:...,active:true}'。 – EugZol

+0

@EugZol我正在使用React開發工具,它不會更新。 – m00saca

+0

你還介意顯示你的'store.js'嗎? – EugZol

回答

2

this.props.dispatch(activeBox());調度以下行動,你的終極版店:

{ 
    type: "CLICK", 
} 

那動作不識別單擊的導航項目,它只是說發生的點擊。同樣的,你的減速會從

{ 
    about: { 
    id: "about", 
    title: "Who I am", 
    active: false 
    }, 
    projects: { 
    id: "projects", 
    title: "What I do", 
    active: false 
    } 
} 

{ 
    about: { 
    id: "about", 
    title: "Who I am", 
    active: false 
    }, 
    projects: { 
    id: "projects", 
    title: "What I do", 
    active: false 
    }, 
    active: true 
} 

你只是將相鄰的積極標誌aboutprojects,而不是他們。查看redux's todomvc示例,瞭解如何最好地識別哪個項目被點擊並讓商店更新得當。一種解決方案是

//navActions.js 
export function activeBox(nav){ 
    return{ 
    type: "CLICK", 
    nav: nav 
    } 
} 

// navReducer.js 
export default function reducer(state = { 
    about: { 
    id: "about", 
    title: "Who I am", 
    active: false 
    }, 
    projects: { 
    id: "projects", 
    title: "What I do", 
    active: false 
    } 
}, action) { 

switch (action.type) { 
    case "CLICK": { 
    // Copy state over to prevent altering previous state 
    let newState = { 
     about: ...state.about, 
     projects: ...state.projects 
    } 
    // Set all nav items to inactive, when you have more navItems you'll want to loop 
    newState.about.active = false 
    newState.projects.active = false 

    // if action.nav is a proper nav item, set it to active 
    if (newState[action.nav]) { 
     newState[action.nav].active = true 
    } 
    return newState 
    break 
    } 
} 

return state 
} 
+0

謝謝你這個徹底的答案。我現在正在研究它,以瞭解如何最好地實施您的建議作爲解決方案。同時感謝您鏈接到todomvc示例 - 有用的資源。所以我將商店的某些部分設置爲「{active:true}」,但不是我想要的部分,現在我明白了。我在底部看到你對''reducer'函數中首次出現的'nav'的評論,但究竟是什麼呢?這是對''的引用,我點擊以啓動'this.props.dispatch(activeBox)'? – m00saca

+0

是的,你需要派遣一個類型爲「CLICK」的動作,以及一些關於哪個導航被點擊的標識。我稱這個「nav」,但它可以很容易地被「navId」或任何最適合你的工具。在我的例子中,你可以調用'this.props.dispatch(activeBox(nav))''你實際上在哪個導航中傳入的地方,可以是id或字符串'about' –

+0

我實現了你的解決方案,太好了,非常感謝。我試圖搞亂localStorage,讓應用程序「記住」刷新後的內容。這是更適合反應路由器還是有一個redux解決方案? – m00saca