Диспетчер Redux не работает

77
7

Добрый вечер и приготовьтесь к большому количеству кода.

Я изучаю, как использовать Redux с React, чтобы разделить состояние между компонентами, и я пытался создать панель навигации, которая изменяет цвета, на основе которых вы нажимаете. На высоком уровне я хочу, чтобы 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>

Поэтому в основном компоненты меняют цвет, когда вы нажимаете на них, и это ДЕЙСТВИТЕЛЬНО ТРЕБУЕТСЯ В РЕАЛЬНОМ случае, я пришел, чтобы узнать. У меня есть мой диспетчер, подключенный правильно в соответствии с учебным пособием, который я просматриваю, и у меня все еще нет успеха в изменении состояния. Возможно, я не совсем понимаю 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;

Благодарим заранее сообщество, я с нетерпением жду вашего понимания, потому что я пытался заставить его работать весь день.

ура

спросил(а) 2021-01-25T15:52:28+03:00 4 месяца, 4 недели назад
1
Решение
77

this.props.dispatch(activeBox()); отправляет следующее действие в ваш магазин redux:

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

Вы просто добавляете активный флаг рядом с about и projects, а не в них. Просмотрите пример redux 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
}

ответил(а) 2021-01-25T15:52:28+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема