derty14
derty14

Reputation: 115

how to solve this problem with render in Redux?

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

Answers (3)

LonelyPrincess
LonelyPrincess

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

Nicolae Maties
Nicolae Maties

Reputation: 2655

let MobileMenuContainer = connect(
  MapStateToProps,
  MapDispatchToProps
)(MobileMenu);

Here is your problem, you need to pass MapStateToProps instead of MapDispatchToProps

Upvotes: 1

Vaibhav Singh
Vaibhav Singh

Reputation: 942

There were a lot of mistakes in the code:

  1. connect takes first argument as MapStateToProps and second as MapDispatchToProps, you are passing it in an incorrect order.
  2. your variable let Menu is defined as a function it should be a Component.
  3. The 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

Related Questions