Reputation: 115
I transferred my project from just React to the React, Redux and react-redux stack and an error occurred. Before transferring to this stack, everything worked adequately. enter image description here. I tried to fix it in 3 days, but it didn’t work out.
My index.js:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import store from "./store/date";
import {BrowserRouter} from "react-router-dom";
import {Provider} from "react-redux";
import App from "./App";
const rerender=()=> {
ReactDOM.render(
<BrowserRouter>
<Provider store={store}>
<App /></Provider></BrowserRouter>, document.getElementById("root")
);
};
rerender();
store.subscribe(()=>{
rerender()
})
My file with date (date.js):
import {combineReducers, createStore} from "redux";
import realtorsDate from "./realtorsDate";
let isMenuVisible = true;
const UpdateMenu = (state = isMenuVisible, action) => {
switch (action.type) {
case 'UpdateMenu' :
let copystate = !state;
return copystate;
default :
return state;
}
};
let menuDate=[
{
Name: "Main",
Symbol: "/",
Src: ""
},
{
Name: "logo",
Symbol: "img",
Src: "./../Images/logo.png"
},
{
Name: "About us",
Symbol: "#",
Src: "about"
},
{
Name: "Our team",
Symbol: "#",
Src: "team"
},
{
Name: "Vacancies",
Symbol: "/",
Src: "work"
},
{
Name: "Advantage",
Symbol: "#",
Src: "adv"
},
{
Name: "Contacts",
Symbol: "#",
Src: "cont"
}
]
let reducers=combineReducers({UpdateMenu,realtorsDate})
const store=createStore (UpdateMenu,menuDate);
export default store;
Container component:
import {connect} from "react-redux";
import MobileMenu from "./menu";
let menuStateText= {
type: "UpdateMenu"
}
let MapStateToProps=(state)=>{
return {
menuDate: state.menuDate}}
let MapDispatchToProps=(dispatch)=>{
return {
UpdateMenu: ()=> {
dispatch (menuStateText)
}
}
}
let MobileMenuContainer=connect(MapDispatchToProps,MapStateToProps)(MobileMenu);
export default MobileMenuContainer
Component:
import React from "react"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faBars} from "@fortawesome/free-solid-svg-icons/faBars";
import "./../css/App.css"
import ParagraphOfMenu from "./paragraphMenu";
class MobileMenu extends React.Component {
render(props) {
debugger
let Menu =()=>{this.props.menuDate.map((el,i) => (
<ParagraphOfMenu el={el} key={i}/>
))}
return (
<div className="mobileMenuBlock">
<FontAwesomeIcon icon={faBars} onClick="return false"></FontAwesomeIcon>
<header className={(this.props.UpdateMenu) ?"hidemenu":"mobilemenu"}>
<nav>
<ul className="">
<Menu></Menu>
</ul>
</nav>
</header>
</div>
);
}
}
export default MobileMenu
link to code: codesandbox
thanks in advance
Upvotes: 0
Views: 200
Reputation: 461
I found a couple of issues in this code, so I'll point them out to you and hope they can help you.
First of all, take a look at this:
const store = createStore(UpdateMenu, menuDate);
What this does is to create a new store and initialize it with the value you passed as an argument. Since you passed a single reducer to the createStore
function, the value assigned to the state
will be the array you had in your menuDate
variable.
Right now you cannot access state.menuDate
because state
it's not an object: it contains the array itself. If you want to get that array, you'll have to update MapStateToProps
method like this:
let MapStateToProps = (state) => {
return { menuDate: state }
}
I've also noticed that you use combineReducers
, but you end up not using the combined reducer for anything.
let reducers = combineReducers({
UpdateMenu,
realtorsDate
});
If you want to use both, you should update the call to createStore
by passing it the combined reducers rather than UpdateMenu
.
createStore(reducers)
If you choose to do so, keep in mind that the store you create will have the following structure:
{
UpdateMenu: [value returned by the UpdateMenu reducer],
realtorsDate: [value returned by the realtorsDate reducer]
}
If you want to apply a different structure for your store, you must change the object you pass to combineReducer
. Here's an example:
combineReducers({
post: postReducer,
topic: topicReducer
})
You should also take a look at how you're calling connect
:
let MobileMenuContainer=connect(MapDispatchToProps,MapStateToProps)(MobileMenu);
You're passing the two arguments in the opposite order. As you can see in the official react-redux
docs, MapStateToProps
should be the first param, and MapDispatchToProps
the second one.
The last, and not least, issue that I found lies in the implementation of the UpdateMenu
reducer itself.
const UpdateMenu = (state = isMenuVisible, action) => {
switch (action.type) {
case 'UpdateMenu' :
let copystate = !state;
return copystate;
default :
return state;
}
};
I'm not really sure about what your action is meant to do, but right now your state contains an array of items. When the action UpdateMenu
triggers, though, that array is replaced by a false
value. This means you're losing all of your data, so you should probably review this.
If you don't prevent this from happening, you'll come accross a new error when calling map
because your state does no longer contain an array after the UpdateMenu
action has been dispatched. The reducer should return a new array with the updated data so everything works as expected.
Upvotes: 1
Reputation: 2655
let MobileMenuContainer = connect(
MapStateToProps,
MapDispatchToProps
)(MobileMenu);
Here is your problem, you need to pass MapStateToProps
instead of MapDispatchToProps
Upvotes: 1
Reputation: 942
There were a lot of mistakes in the code:
connect
takes first argument as MapStateToProps and second as MapDispatchToProps, you are passing it in an incorrect order.let Menu
is defined as a function it should be a Component.Update
method is defined in render method it should instead be defined as a class method. Since you are already and call the method you receive in props there.You can refer this working code: https://codesandbox.io/s/eager-bose-5lejz?fontsize=14&hidenavigation=1&theme=dark
Upvotes: 0