javascript - Redux 调度程序未按预期更改状态

标签 javascript reactjs redux react-redux

我正在学习如何将 Redux 与 React 结合使用,以便在组件之间共享状态,并且我一直在尝试制作一个导航栏,该导航栏可以根据您单击的 div 来更改颜色。在较高的层面上,我希望 Redux 允许我执行以下操作...

<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>

所以基本上,当你点击组件时,它们会改变颜色,这在 React 中很难做到,我已经发现了。我根据我正在观看的教程正确连接了调度程序,但我仍然没有成功更改状态。

也许我不太了解 Redux。我将按照最适合理解我的问题的顺序提供片段,也许您可​​以发现我出错的地方。

附加到index.html的

client.js没什么特别的。

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;

最佳答案

this.props.dispatch(activeBox()); 将以下操作分派(dispatch)到您的 redux 存储:

{
  type: "CLICK",
}

该操作不会识别哪个导航项被单击,它只是表明发生了一次单击。同样,你的 reducer 将从

{
  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
}

关于javascript - Redux 调度程序未按预期更改状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39501786/

相关文章:

javascript - NodeJS 让 Promise 等待 foreach 循环完成

javascript - zing 图表未在 Canvas 中呈现

javascript - 如何找出数组中相似的对象 - React JS

javascript - Redux-form 不读取 SelectField 的值

javascript - 如何在 react 中返回html文本变量并打印为html?

javascript - 触发 Primefaces p :selectOneMenu onchange

javascript - 在 Node.js 中,如何从另一个模块中的模块中的 app.js 访问函数?

javascript - React/Redux URL 不匹配 : When the array item number differs from the object id

javascript - 在 react.js 上下文中获取 html 元素的数据属性

reactjs - 如何根据 Redux 表单中的另一个输入有条件地显示一个输入?