React & Redux: Getting Undefined Error When Accessing Props - reactjs

I am using Redux with React to manage my state; however, I get an undefined error whenever I try to access this particular state that looks good and accessible through Redux Chrome Extension (Please See Image Below)
Based on Redux Chrome Extension, memberDetails object should be available to all components through this.props.memberDetails but I get an undefined error.
The class I am accessing memberDetails from is as follows:
import React, {Component} from 'react';
class Details extends Component {
render = () => {
const memberDetails = this.props.memberDetails;
console.log("memberDetails: ", memberDetails);
return (
<div>
</div>
);
}
}
export default Details;

You are supposed to use mapStateToProps function to get the memberDetails value from store.
Look at this. https://react-redux.js.org/using-react-redux/connect-mapstate
import React, {Component} from 'react';
import { connect } from 'react-redux'
class Details extends Component {
render = () => {
const memberDetails = this.props.memberDetails;
console.log("memberDetails: ", memberDetails);
return (
<div>
</div>
);
}
}
function mapStateToProps(state) {
const { memberDetails } = state
return { memberDetails }
}
export default connect(mapStateToProps)(Details)

Related

React error Expected an assignment or function call and instead saw an expression no-unused-expressions while passing props to child component

im getting Expected an assignment or function call and instead saw an expression no-unused-expressions while trying to pass props to child component.
fetchMovie() make axios request to api and returns a valid JSON object.
im trying to pass the object as a prop to child component and im getting this error
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchMovie } from '../actions/movies';
import { MovieItem } from './MovieItem';
import Spinner from './spinner/Spinner';
import PropTypes from 'prop-types';
export class Movies extends Component {
componentDidMount() {
this.props.fetchMovie();
}
render() {
const { movie } = this.props.movies;
let movieItem;
if (movie === null) {
movieItem = 'loading';
} else {
<MovieItem movie={movie} />
}
return (
<div>
<div className="text-center"><p>{movieItem}</p></div>
</div>
)
}
}
Movies.propTypes = {
movies: PropTypes.object.isRequired,
fetchMovie: PropTypes.func.isRequired
}
const mapStateToProps = state => ({
movies: state.movies
})
export default connect(mapStateToProps, { fetchMovie })(Movies);
how to solve this issue? and what is the error meaning?
Look at the render method, in the else branch you create a MovieItem component, but you don't do anything with it. Looking at your code, I guess you need to assign it to movieItem variable, so it gets than rendered in the p element.

react-async-poll with a connected component

Looking at the docs for react-async-poll I'm following the Usage example to integrate asyncPoll into my component, but I'm getting a Uncaught TypeError: dispatch is not a function complaint from within my onPollinterval function
import React, { Component } from 'react';
import { connect } from 'react-redux';
import asyncPoll from 'react-async-poll';
import { fetchCaCities, } from '../actions';
import MyMap from './my-map';
class CaliforniaMap extends Component {
componentDidMount() {
this.props.fetchCaCities();
}
render() {
return (
<div>
<h1>California Map</h1>
<MyMap center={[37.5, -120]} zoom={6} layers={[this.props.caCities]} />
</div>
);
}
}
const onPollInterval = (props, dispatch) => {
console.log(dispatch); // undefined
return dispatch(fetchCaCities());
};
const mapStateToProps = state => ({
caCities: state.map.california.caCities,
});
export default asyncPoll(60 * 1000, onPollInterval)(connect(
mapStateToProps, { fetchCaCities }
)(CaliforniaMap)
Maybe react-async-poll doesn't work for connected components?
According to the docs:
The dispatch parameter is only passed to [onInterval] if it is
available in props, otherwise it will be undefined.
The example they give is confusing because it does not define dispatch anywhere, but they show onPollInterval using it.

action passed down from connect decorator is initially undefined

I have the following smart component and I am specifying the initialUpload function is a required func:
import React, { Component, PropTypes } from 'react';
import UploadForm from '../../components/UploadForm/UploadForm';
import HeaderSelection from '../../components/HeaderSelection/HeaderSelection';
import { initialUpload } from '../../redux/modules/Upload';
import { connect } from 'react-redux';
console.log(typeof initialUpload); //function
#connect((state) => {
return {
file: state.getIn(['upload', 'file'])
};
}, {
initialUpload
})
export default class Home extends Component {
static propTypes = {
initialUpload: PropTypes.func.isRequired
};
render() {
return (
<div>
<UploadForm handleFilesChange={this.props.initialUpload}/>
<HeaderSelection/>
</div>
);
}
}
But I get the error message:
warning.js:36Warning: Failed prop type: The prop initialUpload is
marked as required in Connect(Home), but its value is undefined.
The function is wrapped in dispatch and passed down the component hierarchy fine so I am confused as to what is going on.
#connect is assigning the static propTypes to the resulting rapping component and not to Home itself, which is rather a weird behaviour! I think it is caused by ES7 transformation, this behaviour was not present in previous versions
A work around is to define the propTypes on the wrappedComponent outside class definition:
#connect(...)
export default Home extends Component{
render() {
// ....
}
}
Home.WrappedComponent.propTypes = {
initialUpload: PropTypes.func.isRequired
}
another option would be not to use the decorator & use connect directly

Which way should I use for Connector in Redux?

I seen 2 ways of doing the same thing but I am not sure what is the proper way.
Component
import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {selectUser} from '../actions/index'
class UserList extends Component {
renderList() {
return this.props.users.map((user) => {
return (
<li
key={user.id}
onClick={() => this.props.selectUser(user)}
>
{user.first} {user.last}
</li>
);
});
}
render() {
return (
<ul>
{this.renderList()}
</ul>
);
}
}
// Get apps state and pass it as props to UserList
// > whenever state changes, the UserList will automatically re-render
function mapStateToProps(state) {
return {
users: state.users
};
}
// Get actions and pass them as props to to UserList
// > now UserList has this.props.selectUser
function matchDispatchToProps(dispatch){
return bindActionCreators({selectUser: selectUser}, dispatch);
}
// We don't want to return the plain UserList (component) anymore, we want to return the smart Container
// > UserList is now aware of state and actions
export default connect(mapStateToProps, matchDispatchToProps)(UserList);
https://github.com/buckyroberts/React-Redux-Boilerplate
Or
import React from "react"
import { connect } from "react-redux"
import { fetchUser } from "../actions/userActions"
import { fetchTweets } from "../actions/tweetsActions"
#connect((store) => {
return {
user: store.user.user,
userFetched: store.user.fetched,
tweets: store.tweets.tweets,
};
})
export default class Layout extends React.Component {
componentWillMount() {
this.props.dispatch(fetchUser())
}
fetchTweets() {
this.props.dispatch(fetchTweets())
}
render() {
const { user, tweets } = this.props;
if (!tweets.length) {
return <button onClick={this.fetchTweets.bind(this)}>load tweets</button>
}
const mappedTweets = tweets.map(tweet => <li>{tweet.text}</li>)
return <div>
<h1>{user.name}</h1>
<ul>{mappedTweets}</ul>
</div>
}
}
https://github.com/learncodeacademy/react-js-tutorials/tree/master/5-redux-react
The first way uses 2 different functions mapStateToProps() and matchDispatchToProps() while the other way uses #connect(....).
When I use the #connect I get a whole bunch of warnings saying that it has not been finalized and might change.
The # symbol is a decorator which is still considered experimental. So I would use that at your own risk. Your first code block is the safer way to do it as described in the official docs. Both blocks essentially do the same thing but decorators are more sugar than anything.
References:
https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options
What's the '#' (at symbol) in the Redux #connect decorator?
I think the first method will give you less problems in the end. Someone else can chime in though too.
The answer by Jackson is right in every sense however he is missing out the importance of using the first version for the usage of unit testing. If you want to be able to unit test a component (which usually means testing with the unconnected version) you need to be able to export the connected and unconnected component.
Using your example and assuming you are using jest/enzyme you could do something like this:
// notice importing the disconnected component
import { UserList } from '../relative/file/path/UserList'
import { mount } from 'enzyme'
describe('UserList', () => {
it('displays the Username', () => {
const users = [{fist: 'Person', last: 'Thing'}, ... ]
const UserList = mount(<UserList users={users} />)
export(UserList.find('li')[0].text()).toEqual('Person Thing')
});
});
Once you build larger projects being able to unit test will provide sanity to your coding life. Hope this helps

in reactjs, how to access the component method from other class by using ES6 method?

in reactjs, how to access the component method from other class by using ES6 method?
I am facing a problem in React JS. I'm unable to fetch the component method from other class by using enum.
Please help me out to solve this issue.
I'm trying in ECMA6 format.
Thanks in advance.
import React from 'react';
import {Component} from 'react';
const Message = (props) =>
{
const Enum = require('node-enumjs');
var Days = ({
constants: {
Monday: {
say1() {
return 'mondays are bad!';
}
},
Tuesday: {
say: function () {
return this.name() + "s are ok...";
}
},
Wednesday: {
say: function () {
return this.name() + " is the middle of the week...";
}
}
}
})
}
export default Message;
from Message component i have access to say() inside monday.
import React from 'react';
import {Component} from 'react';
import Message from '../../../message';
export default class Content extends Component {
sai() {
return(
<div>
<h1>{Message.Monday.say1()}</h1>
<h1>{Message.Monday.say2()}</h1>
</div>
)}
render() {
return (
<div className="page-title">
<center> Content </center>
<button name="press" onClick = {this.sai}>press</button>
</div>
);
}
}
no error, but, when event rise in browser error like this: flows_content.js:14 Uncaught TypeError: Cannot read property 'say1' of undefined

Resources