having issues displaying objects from state - javascript

I am having an issue with getting the data from my state I need the information from the employee state to display the pages in referring to are Employee.js and EmployeeItem.js in my repo.
I can map through the state and display a number of blank objects based on how many entries are in the state but I am having trouble displaying and information for the individual objects
How the page currently renders
How I need the page to render
Employee.js
import React, {Fragment, useEffect} from 'react'
import {Link} from 'react-router-dom'
import {connect} from 'react-redux'
import Spinner from '../../layout/Spinner'
import {getEmployees} from '../../../actions/employee'
import EmployeeItem from './EmployeeItem'
import PropTypes from 'prop-types'
const Employees = ({ getEmployees, employee: {employees, loading}}) => {
useEffect(() => {
getEmployees()
}, [])
return (
<Fragment>
{loading ? <Spinner/> :
<Fragment>
<section className="content bg-light">
<h1 className="x-large text-primary title">Employees</h1>
<div className="add">
<Link to="/employees/new"><i className="fas fa-plus-circle text-primary x-large"></i></Link>
</div>
{employees.length > 0 ? (
employees.map(employee => (
<EmployeeItem key={employee._id} profile={employee} />
))
) : <h4>No Employees Found....</h4>}
</section>
</Fragment>
}
</Fragment>
)
}
Employees.propTypes = {
getEmployees: PropTypes.func.isRequired,
employee: PropTypes.object.isRequired,
}
const mapStateToProps = state => ({
employee: state.employee
})
export default connect(mapStateToProps, {getEmployees})(Employees)
EmployeeItem.js
import React from 'react'
import {Link} from 'react-router-dom'
import PropTypes from 'prop-types'
const EmployeeItem = ({employee: name, employement, _id}) => {
return (
<div className="employee-container">
<Link to={`/employees/${_id}`}>
<div className="employee-icon bg-white">
<div className="circle-sal">
<h4 className="large initials">J D</h4>
</div>
<p className="lead-2">{name}</p>
</div>
</Link>
</div>
)
}
EmployeeItem.propTypes = {
employee: PropTypes.object.isRequired,
}
export default EmployeeItem
[What is in the state:
Any help on fixing this would be much appreciated.

If you look at the EmployeeItem. You are assigning employee value to profile prop.
<EmployeeItem key={employee._id} profile={employee} />
and you are trying to access the value wrongly.
const EmployeeItem = ({employee: name, employement, _id}) => {
}
You could have done either this way
<EmployeeItem key={employee._id} profile={employee} />
and in EmployeeItem
const EmployeeItem = ({ profile: { name, _id } }) => {
}
or
<EmployeeItem key={employee._id} {...employee} />
and in EmployeeItem
const EmployeeItem = ({ name, _id }) => {
}

Related

Sharing state with 2 components Redux

Trying to share the state between 2 components so the dashboard and the displayed component can change states simultaneously. Exmp: Switch from dashboard view to application view and display application component. Problem: I can't wrap my head around what I'm missing here and why the state does not work on my dashboard component.
Redux Slice:
import { createSlice } from '#reduxjs/toolkit';
const initialState = {
selector: 0,
};
export const dashboardSlice = createSlice({
name: 'mainDashState',
initialState,
reducers: {
setSelector: (state, action) => {
state.selector = action.payload;
},
},
});
export const { setSelector } = dashboardSlice.actions;
export default dashboardSlice.reducer;
Redux Store:
import { configureStore } from "#reduxjs/toolkit";
import mainDashSlice from './slices/mainDashSlice';
export const store = configureStore({
reducer: {
mainDashState: mainDashSlice,
},
})
Dashboard.jsx:
import { React } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import '../../css/SideBar.css';
import { UilSignOutAlt } from '#iconscout/react-unicons';
import Logo from '../../../../assets/img/companyLogo.jpg';
import { SidebarData } from '../../Data/Data';
import { setSelector } from '../../../../features/redux/slices/mainDashSlice';
// import Applications from '../applicationsTab/Applications';
function SideBar() {
const selector = useSelector((state) => state.selector);
const dispatch = useDispatch();
console.log(selector);
return (
<div className="Sidebar">
{/* logo */}
<div className="logo">
<img src={Logo} alt="logo" />
<span>Company Name</span>
</div>
{/* menu */}
<div className="menu">
{SidebarData.map((item, index) => (
/* eslint-disable */
<div
role="menu"
className={selector === index ? 'menuItem active' : 'menuItem'}
key={index}
onClick={() => dispatch(setSelector(selector))}
onKeyDown={() => dispatch(setSelector(selector))}
>
<item.icon />
<span>{item.heading}</span>
</div>
))}
<div className="menuItem">
<UilSignOutAlt />
</div>
</div>
</div>
);
}
export default SideBar;
TL;DR:
When clicking on the dashboard "Application" change the state in redux for another component as well to re-render the main tab.
Thanks guys! Do need to understand what I'm doing wrong...

Cannot read property 'params' of undefined with Redux

I am trying to post some data of an object when i click on "show's button". So i want to keep its id. So i used this code in my container:
import {connect} from "react-redux";
import ShortcutCard from "./ShortcutCard";
const mapStateToProps = (state,ownProps) => {
let id = ownProps.match.params.id;
return{
shortcut : state.raccourcis.shortcuts.find(shortcut => shortcut.id ===id)
}
}
const mapDispatchToProps = dispatch => ({
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(ShortcutCard);
**and this one like a component(in an other file) :**
import React, {Component} from 'react';
import './ShortcutCard.scss';
import {Link, Route} from "react-router-dom";
class ShortcutCard extends Component {
render() {
const {shortcut} = this.props;
return (
<div className="col mb-4 cardContainer">
<div className="card">
<div className="card-body">
<h2 className="card-title">{shortcut.title}</h2>
<p className="card-text">{shortcut.context}</p>
<img src={process.env.REACT_APP_UPLOADS_DIR + '/' + shortcut.software.logo} className="card-img-top" alt={shortcut.software.name}/>
<Link to={'/Excerpts/' + shortcut.id} >
<button>shows</button>
</Link>
</div>
</div>
</div>
);
}
}
export default ShortcutCard;
I dont know i got an error. "paramas undefined"
PS: i am a newbie on react and redux.

Classless react states?

Im trying to build a simple app with react-boilerplate, the containers(basically views) and components do not use classes to create new components, instead they are basic functions. Typically you add a constructor or direct state to a class, since there are no classes i dont know where to add the state definition. Nowhere ive added a constructer or state definition works, where can you add simple react (NO redux) state list or constructor within this pattern for this view?
example of a container
/*
* HomePage
*
* This is the first thing users see of our App, at the '/' route
*/
import React, { useEffect, memo } from 'react';
import PropTypes from 'prop-types';
import { Helmet } from 'react-helmet';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { createStructuredSelector } from 'reselect';
import { useInjectReducer } from 'utils/injectReducer';
import { useInjectSaga } from 'utils/injectSaga';
import {
makeSelectRepos,
makeSelectLoading,
makeSelectError,
} from 'containers/App/selectors';
import H2 from 'components/H2';
import ReposList from 'components/ReposList';
import AtPrefix from './AtPrefix';
import CenteredSection from './CenteredSection';
import Form from './Form';
import Input from './Input';
import Section from './Section';
import messages from './messages';
import { loadRepos } from '../App/actions';
import { changeUsername, setHomeVisible } from './actions';
import { makeSelectUsername, makeHomeVisible } from './selectors';
import reducer from './reducer';
import saga from './saga';
import NavBar from './NavBar';
import ButtonLink from './ButtonLink';
const key = 'home';
export function HomePage({
username,
loading,
error,
repos,
onSubmitForm,
onChangeUsername,
homeVisible,
makeHomeVisible,
setHomeVisible
}) {
useInjectReducer({ key, reducer });
useInjectSaga({ key, saga });
useEffect(() => {
// When initial state username is not null, submit the form to load repos
if (username && username.trim().length > 0) onSubmitForm();
}, []);
const reposListProps = {
loading,
error,
repos,
};
return (
<article>
<Helmet>
<title>title</title>
<meta
name="description"
content=""
/>
</Helmet>
<NavBar>
<ButtonLink to="/" onClick={makeHomeVisible}>
<FormattedMessage {...messages.websites} />
</ButtonLink>
<ButtonLink to="/apps" >
<FormattedMessage {...messages.apps} />
</ButtonLink>
</NavBar>
<div className={`home ${this.state.visible === false ? 'hidden': ''}`}>
<Section>
<H2>
<FormattedMessage {...messages.trymeHeader} />
</H2>
<Form onSubmit={onSubmitForm}>
<label htmlFor="username">
<FormattedMessage {...messages.trymeMessage} />
<AtPrefix>
<FormattedMessage {...messages.trymeAtPrefix} />
</AtPrefix>
<Input
id="username"
type="text"
placeholder="mxstbr"
value={username}
onChange={onChangeUsername}
/>
</label>
</Form>
<ReposList {...reposListProps} />
</Section>
</div>
</article>
);
}
HomePage.propTypes = {
loading: PropTypes.bool,
homeVisible: PropTypes.bool,
error: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
repos: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
onSubmitForm: PropTypes.func,
username: PropTypes.string,
onChangeUsername: PropTypes.func,
makeHomeVisible: PropTypes.func,
};
const mapStateToProps = createStructuredSelector({
repos: makeSelectRepos(),
username: makeSelectUsername(),
loading: makeSelectLoading(),
error: makeSelectError(),
homeVisible: makeHomeVisible(),
});
export function mapDispatchToProps(dispatch) {
return {
onChangeUsername: evt => dispatch(changeUsername(evt.target.value)),
makeHomeVisible: evt => dispatch(setHomeVisible(evt.target.value)),
onSubmitForm: evt => {
if (evt !== undefined && evt.preventDefault) evt.preventDefault();
dispatch(loadRepos());
},
};
}
const withConnect = connect(
mapStateToProps,
mapDispatchToProps,
);
export default compose(
withConnect,
memo,
)(HomePage);
As per the React Docs, you can use the useState hook to save data to state. There is no "state list or constructor" but you can simply access the props you pass in and decide to save those into state if they are going to be manipulated - if not stick to using the props.
Codesandbox Demo
Basic Example:
function Child(props) {
let [name, setName] = useState(props.data.name);
function updateName () {
setName('The Dude');
}
return (
<div className="App">
<h2>{name}</h2>
<button onClick={updateName}>Update</button>
</div>
);
};
function App() {
let [data, setData] = useState({name: 'dude'});
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Child data={data}/>
</div>
);
}

Error: Invalid value of type object for mergeProps argument

I'm setting up my app with redux, and i'm new to it. I want to make onClick() event to take item's id but im getting error.
I searched a lot of answers here, but they didn't help me a lot.
Documentation says, that i'm not connecting my action right, but I found no good explanation, only example with toDo, which is not enough for me.
Products.js(where I want my onClick())
import React, { Component } from "react";
import Navbar from "../navbar/Navbar";
import Product from "../lists/Product";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { getItems } from "../../actions/getItems";
import { getDetails } from "../../actions/getDetails";
class Products extends Component {
componentDidMount() {
this.props.getItems();
}
render() {
return (
<div className="container-fluid products">
<Navbar />
<div className="container">
<h1 className="title display-3 text-center pt-2">
<b>Our Products</b>
</h1>
<div className="underline" />
<div className="py-5">
<div className="container">
<div className="row">
{this.props.shopItems.items.map(item => {
return (
<div
onClick={() =>this.props.getDetails(item.id)}
className="col-lg-3 col-md-6 col-sm-6 col-xs-9"
key={item.id}
>
<div className="card-deck">
<Product
name={item.name}
brand={item.brand}
img={item.img}
price={item.price}
/>
</div>
</div>
);
})}
</div>
</div>
</div>
</div>
</div>
);
}
}
Products.propTypes = {
shopItems: PropTypes.object.isRequired,
getDetails:PropTypes.func.isRequired
};
const mapStateToProps = state => ({
shopItems: state.shopItems
});
export default connect(
mapStateToProps,
{ getItems }
)(Products);
getDetails.js
import {SHOW_DETAILS} from './types';
import {data} from '../data/data';
export const getDetails = id => dispatch =>{
const detailProduct = data.find(item => item.id === id)
dispatch({
type:SHOW_DETAILS,
payload:detailProduct
})
}
detailsReducer.js
import { SHOW_DETAILS } from "../actions/types";
const initialState = {
detailProduct: {}
};
export default (state = initialState, action) => {
switch (action.type) {
case SHOW_DETAILS:
return {
detailProduct: action.payload
};
default:
return state;
}
};
index.js(root reducer)
import {combineReducers} from 'redux'
import itemsReducer from './itemsReducer'
import detailsReducer from './detailsReducer';
export default combineReducers({
shopItems:itemsReducer,
detailProduct:detailsReducer
})
Store.js
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import rootReducer from './reducers/index';
const initialState = {};
const middleware = [thunk];
let store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(...middleware),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
);
export default store;
I expect:
Connect action getDetails to component Products.js.
Make onClick() to grab needed item's id.
Use find() item by it's id, receive item's info in state detailProduct.
No errors.

React component throws an error after refreshing [duplicate]

This question already has answers here:
Unable to pass props to component through react-router
(3 answers)
When I link javascript file in html it sends a request to server and causing error
(3 answers)
Closed 4 years ago.
I am having a trouble with this minor problem . When i refresh my page , it gives an error `
GET http://localhost:3000/drink/bundle.js net::ERR_ABORTED 404 (Not Found)
Refused to apply style from 'http://localhost:3000/drink/style.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
I know that this a problem with rout but i couldnt find a way to solve it .
Here is my code `
import * as React from "react"; import {connect} from "react-redux"; import {drinksSelector} from "../selectors" import {getDrinksList, getNameFilter} from "../actions"; import Drink from "./Drink"; import SearchIcon from "./SvgIcons";
class Drinks extends React.Component {
componentDidMount() {
this.props.dispatchDrinksList();
}
handleInputChange = (e: any) => {
e.preventDefault();
this.props.dispatchNameFilter(e.target.value) }
render() {
const {drinks} = this.props;
return (
<div>
<header className="main-header">
<form className="main-header__from">
<div className="search-wrapper">
<input autoComplete='off'
type="text"
name="search"
placeholder="Search"
className="main-header__input"
onChange={this.handleInputChange}/>
<SearchIcon />
</div>
</form>
</header>
<ul>
{drinks.map((drink: any) => <Drink key={drink.idDrink} url={drink.strDrinkThumb} name={drink.strDrink} id={drink.idDrink}/>)}
</ul>
</div>
); } } const mapStateToProps: any = (state: any) => drinksSelector(state);
const mapDispatchToProps: any = (dispatch: ReturnType<typeof mapDispatchToProps>) => ({ dispatchDrinksList() {
dispatch(getDrinksList()); },
dispatchNameFilter(value: any) {
dispatch(getNameFilter(value));
} });
export default connect(mapStateToProps, mapDispatchToProps)(Drinks);
Above is the dashboard page where i render list of drinks, and when clicking on them the routes changes to /drink/someId
import * as React from 'react'; import { connect } from 'react-redux';
import { NavLink } from "react-router-dom";
const Drink = ({ url = "", name, id }: any): any => (
<li>
<NavLink to={`/drink/${id}`}>
<h2>{name}</h2>
<img src={url} alt={name} height="350" width="350"/>
</NavLink>
</li> );
export default Drink;
And this is the page where after refreshing i got an error `
import * as React from 'react';
import { connect } from 'react-redux';
import { NavLink } from "react-router-dom";
import {getDrinkInfo} from "../actions";
class DrinkInfo extends React.Component<any, any> {
componentDidMount() {
const id = localStorage.getItem("id");
if (!id) {
localStorage.setItem("id", this.props.match.params.id);
}
this.props.dispatchDrinkInfo(localStorage.getItem("id"));
}
render() {
const { drink } = this.props;
console.log(this.props, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
return (
<div className="drink-info">
<header className="drink-info__header">
<button onClick={() => this.props.history.goBack()} className="drink-info__button">Go Back</button>
<h2 className="drink-info__title">{drink && drink.strDrink}</h2>
</header>
<section className="details">
<div className="details__image-box">
<img src={drink && drink.strDrinkThumb} alt={drink && drink.strDrink} height="350" width="350"/>
</div>
<div className="details__info">
<p className="details__ingredients"></p>
<div className="details__prepare">
<h3 className="details__prepare-heading">How to prepare</h3>
<p className="details__prepare-text">
{drink && drink.strInstructions}
</p>
</div>
</div>
</section>
</div>
)
}
}
const mapStateToProps: any = (state: any) => {
return {
drink: state.drink.get("drinkInfo") || {}
}
}
const mapDispatchToProps: any = (dispatch: ReturnType<typeof mapDispatchToProps>) => ({
dispatchDrinkInfo(id: number) {
dispatch(getDrinkInfo(id));
}
});
export default connect(mapStateToProps, mapDispatchToProps)(DrinkInfo);
My routers `
import * as React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import DashboardPage from '../components/DashboardPage';
import DrinkInfo from '../components/DrinkInfo';
import NotFoundPage from '../components/NotFoundPage';
const AppRouter = () => (
<BrowserRouter>
<React.Fragment>
<Switch>
<Route path="/" component={DashboardPage} exact/>
<Route path="/drink/:id" component={DrinkInfo}/>
<Route component={NotFoundPage} />
</Switch>
</React.Fragment>
</BrowserRouter>
);
export default AppRouter;

Categories