I am following this tutorial on React-Redux and I stumbled upon error on 1st part of section "React Redux tutorial: asynchronous actions in Redux, the naive way".
Post.componentDidMount
src/js/components/Posts.js:12
9 |
10 | componentDidMount() {
11 | // calling the new action creator
> 12 | this.props.getData();
| ^ 13 | }
14 |
15 | render() {
My understanding is that props from store is not passed down from the App component to Posts component. I have repeated the steps several times but I still cannot see the exact culprit. The source code from Git works just fine. I noticed, there are difference between my local and that of the GIT repo.
This is my package.json
{
"name": "react-redux-study",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.5.0",
"#testing-library/user-event": "^7.2.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"react-redux": "^7.2.0",
"redux": "^4.0.5"
}
}
And this is the package.json from the Git repo.
UPDATE: Added my App.js and Posts.js
App.js
import React from "react";
import List from "./List";
import Form from "./Form";
import { Post } from "./Posts";
const App = () => (
<>
<div>
<h2>Articles</h2>
<List />
</div>
<div>
<h2>Add a new article</h2>
<Form />
</div>
<div>
<h2>API posts</h2>
<Post />
</div>
</>
);
export default App;
Posts.js
import React, { Component } from "react";
import { connect } from "react-redux";
import { getData } from "../actions/index";
export class Post extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
// calling the new action creator
this.props.getData();
}
render() {
return null;
}
}
export default connect(
null,
{ getData }
)(Post);
I can actually just move on and use the source code from Git but I do want to understand what is the exact issue.
Issue :
// posts.js
export class Post extends Component { // <---- First : Export
...
}
export default connect( // <----- Second : Export
null,
{ getData }
)(Post);
// inside app.js
// you are importing first import, not the default which is connecting to you store
import { Post } from "./Posts";
Solution :
Change this line
import { Post } from "./Posts";
To
// import the default one
import Post from "./Posts";
In app component
<Post getData={postdata} />
In Posts component you can get data like this.
componentDidMount() {
let posts=this.props.getData;
}
Related
Hi guys I'm new to Reactjs, I can run <h1>Hello World </h1> in App.js. But when I use <Container></Container> in Reactstrap even though I have done all the imports, I get a blank page in the browser. App.js is not rendered when I use <Container></Container>.I am not getting any errors either.
App.js => rendered
import React, { Component } from 'react';
import { Container, Row } from 'reactstrap';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<h1>Hello World</h1>
</div>
);
}
}
export default App;
App.js => not rendered
import React, { Component } from 'react';
import { Container, Row } from 'reactstrap';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<Container>
<h1>Hello World</h1>
</Container>
</div>
);
}
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import 'bootstrap/dist/css/bootstrap.min.css';
ReactDOM.render(
<App />,
document.getElementById('root')
);
package.json
{
"name": "test-react-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"bootstrap": "^5.1.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "0.9.5",
"reactstrap": "^9.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
Hey here it looks like react-scripts is low version.I upgraded it to 4.0.0 and added the following in package.json
,
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
Problem solved, thank you.
I'm creating a component which takes in two props. The first is a list of strings e.g. ['string1', 'string2'] and the second is a list of list of strings e.g. [['string1arr1' ,'string2arr1'], ['string3arr2', 'string4arr2']].
The is roughly what my component looks like:
import React from 'react';
import PropTypes from 'prop-types';
export default function ComponentName (props){
//insert component code here
}
ComponentName.propTypes = {
one: PropTypes.arrayOf(PropTypes.string).isRequired,
two: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)).isRequired,
}
When I pass through a prop with a different datatype, e.g.
<ComponentName one={123} two={'abc'} />
No PropTypes error occurs and the component executes as normal.
I've been going through several different tutorials trying to see what it is I've done wrong and from what I can see I'm using poropTypes correctly. I've also tried using simpler requirements such as one: PropTypes.string.isRequired and it still didn't work.
Version of react and prop-types installed:
"react": "^17.0.2",
"prop-types": "^15.8.1"
Babel Dependencies:
"#babel/core": "^7.16.7",
"#babel/plugin-proposal-class-properties": "^7.16.7",
"#babel/preset-env": "^7.16.7",
"#babel/preset-react": "^7.16.7",
"babel-loader": "^8.2.3",
It now works and I'm not sure what I did to fix it :/
It looks right. However I am not sure if your example above is the same semantics you are using in your code. You can't declare export default ComponentName (props), ComponentName is unknown, neither a function or a class. Try something like this instead and maybe it'll solve your problem:
import React from 'react';
import PropTypes from 'prop-types';
function ComponentName (props){
//insert component code here
}
ComponentName.propTypes = {
one: PropTypes.arrayOf(PropTypes.string).isRequired,
two: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)).isRequired,
}
export default ComponentName;
Edit:
Your code works here for me:
package.json
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.14.1",
"#testing-library/react": "^11.2.7",
"#testing-library/user-event": "^12.8.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"web-vitals": "^1.1.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
App.js
import logo from "./logo.svg";
import "./App.css";
import ComponentName from "./ComponentName";
function App() {
return (
<div className="App">
<header className="App-header">
<ComponentName one={["123"]} two={[["923939"]]} />
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
ComponentName.js
import React from "react";
import PropTypes from "prop-types";
export default function ComponentName() {
return <div>ComponentName</div>;
}
ComponentName.propTypes = {
one: PropTypes.arrayOf(PropTypes.string).isRequired,
two: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)).isRequired,
};
I'm connecting store to my react application, But it gives me error TypeError: state is undefined
store/index.js(Creating Reducer function)
import {createStore} from 'redux';
const counterReducer = (state:{counter:0},action) => {
if(action.type==='increment')
{
return {
counter: state.counter + 1
}
}
if (action.type === 'decrement') {
return {
counter: state.counter - 1
}
}
return state;
}
const store = createStore(counterReducer);
export default store;
main index.js(Main index of my file)
import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import store from './store/index';
import './index.css';
import App from './App';
ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
Now I'm using my Counter components like this:(src/components/Counter.js)
import classes from './Counter.module.css';
import {useSelector} from 'react-redux';
const Counter = () => {
const counter = useSelector(state => state.counter);
const toggleCounterHandler = () => {};
return (
<main className={classes.counter}>
<h1>Redux Counter</h1>
<div className={classes.value}>{counter}</div>
<button onClick={toggleCounterHandler}>Toggle Counter</button>
</main>
);
};
export default Counter;
here is my package.json:
{
"name": "redux-basics",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.11.9",
"#testing-library/react": "^11.2.5",
"#testing-library/user-event": "^12.6.3",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-redux": "^7.2.4",
"react-scripts": "4.0.2",
"redux": "^4.1.0",
"web-vitals": "^1.1.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Error:
TypeError: state is undefined
Counter/counter<
C:/Users/nikku/Desktop/redux-project/src/components/Counter.js:6
3 |
4 |
5 | const Counter = () => {
> 6 | const counter = useSelector((state) => state.counter);
7 | const toggleCounterHandler = () => {};
8 |
9 | return (
useSelector should get state as argument by default right? but here it is saying it is undefined. Ca you please share you thoughts? Did I do something wrong ?
In order to initialize a default state, you need to use the = assignment operator
const counterReducer = (state = {counter:0},action) => {
Default state is initialized like this. This will fix your issue.
function appReducer(state = MyInitialState, action) {
switch (action.type) {
case "my_custom_type":
return {
...state
};
default:
return state;
}
}
I'm trying to deploy my react application on my Cloud Web server. But I get the message "Cannot read property 'Component' of undefined".
Here is my code:
//App.js
import React from 'react';
import './App.css';
import './bootstrap.min.css';
import Listitems from './Listitems.js';
import Cart from './Cart.js';
import Products from './Products.json'
class App extends React.Component{
constructor(props){
super(props);
this.handler = this.handler.bind(this)
this.state = {
inCart:[],
ref:[],
revenue:0
}
}
handler(obj, ref) {
this.setState({
inCart: obj,
ref:ref
});
var x;
var revenue = [];
const reducer = (accumulator, currentValue) => accumulator + currentValue;
for(x in obj){
revenue.push(obj[x].price * obj[x].quantity)
}
if(revenue.length !== 0) {
this.setState({revenue:revenue.reduce(reducer)})
} else {
this.setState({revenue:0})
}
}
render(){
var x;
var cartLength = 0;
for(x in this.state.inCart){
cartLength += this.state.inCart[x].quantity
}
return (
<div className="App " >
<div className="container-fluid">
<nav className="navbar navbar-light bg-light shadow w-100">
<a className="navbar-brand" href="www.google.fr" >Mon projet panier</a>
<div>Panier <span data-v-d39b0b74="" className="badge badge-success">{cartLength}</span></div>
</nav>
<div id="mdm-cart" className="container">
<h1 className="title border-bottom mb-5 display-1">Mon panier</h1>
<div className="content">
<div className="row">
<div className="basket col-md-8">
<Cart viewCart={this.state.viewCart} handler={this.handler} reference={this.state.ref} inCart={this.state.inCart} revenue={this.state.revenue}/>
</div>
<div className="liste col-md-4">
<h2>Produits en relation :</h2>
<Listitems key={Products.id} data={Products} handler={this.handler} reference={this.state.ref} inCart={this.state.inCart}/>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default App;
I've also tried to use other import method like :
const { React } = require('react');
import React, { Component } from 'react';
Here is the error message :
Uncaught TypeError: Cannot read property 'Component' of undefined
at Module.<anonymous> (App.js:15)
at l ((index):1)
at Object.<anonymous> (main.e870a004.chunk.js:1)
at l ((index):1)
at a ((index):1)
at Array.e ((index):1)
at main.e870a004.chunk.js:1
Edit : Add Package.json file
{
"name": "Mon projet panier",
"version": "0.1.0",
"private": true,
"dependencies": {
"#babel/polyfill": "^7.7.0",
"babel-plugin-import": "^1.13.0",
"bootstrap": "^4.4.1",
"customize-cra": "^0.9.1",
"react": "^16.12.0",
"react-app-rewired": "^2.1.5",
"react-bootstrap": "^1.0.0-beta.16",
"react-dom": "^16.12.0",
"react-scripts": "3.2.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#babel/cli": "^7.7.7",
"#babel/core": "^7.7.7",
"#babel/preset-env": "^7.7.7"
}
}
One thing that is odd is that the error is located in App:15 but the code need to know what is React.Component in order to go there.
If anyone have any clue, I'll appreciate !
Try this: import React, { Component } from 'react';
Component of undefined means that its parent which is React is undefined, so either your server environment doesn't support React build pack or take a look at the build script webpack configuration.
I finally found the problem.
The files and folders were mixed up serveur side, App.js was in the wrong place. The server didn't even start at all because of this. The error made me think that the server started but were stopped because of the import React.
Anyway, I reoganized the server's folder and restart the server. And it works.
Thanks for you help !
What is the proper way to wire typescript and react-router together when using render prop and a lambda function to pass state and props to child components?
I'm on a super rocky road trying to wire React Router to TypeScript.
I need to pass props and state from my parent component to its children
rendered by React Router. To do so I'm using the render prop as explained here
To fix:
Lambdas are forbidden in JSX attributes due to their rendering performance impact
I wrote a separate method to fix the Lambda error and passed it to render in Route i.e:
public gameRoute = (props: any, state: object) => {
return <Game {...props} {...this.state} />
}
public render(): JSX.Element {
const { person, loading, error } = this.state
return (
<BrowserRouter>
<div className="App">
<ul>
<li>
<Link to="/">home</Link>
</li>
<li>
<Link to="/play-game">Play Game!</Link>
</li>
</ul>
<Switch>
<Route path="/play-game" render={this.gameRoute} />
</Switch>
</div>
</BrowserRouter>
)
}
The main problem is that TypeScript errors:
Trying to work around TypeScript and React Router errors, I added the following types to my child component:
// Child Component
import React from 'react'
import { RouteComponentProps } from 'react-router-dom'
interface GameProps extends RouteComponentProps<any>, React.Props<any> {
person: object[] | any
loading: boolean | string
error: null
}
export const Game: React.SFC<GameProps> = ({ person }) => (
<p className="error">Game is ON! {person}</p>
)
Then I wrote types to my parent component i.e:
// Parent Compoment
import React, { Component } from 'react'
import { StaticContext } from 'react-router'
import { BrowserRouter, Link, Route, RouteComponentProps, Switch } from 'react-router-dom'
import './App.css'
import { Error } from './Error/Error'
import { Game } from './Game/Game'
import { Loading } from './Loading/Loading'
interface AppProps extends RouteComponentProps<any> { }
interface AppState {
person: object[]
loading: boolean | string
error: null
}
export default class App extends Component<AppProps, AppState> {
public state = {
error: null,
loading: true,
person: [],
}
public async componentDidMount() {
const url = 'myApi'
try {
const res = await fetch(url)
const data = await res.json()
this.setState({ person: data, loading: false })
} catch (error) {
this.setState({ error, loading: false })
console.error(error)
}
}
public gameRoute = (props: any, state: object) => {
return <Game {...props} {...this.state} />
}
public render(): JSX.Element {
const { person, loading, error } = this.state
return (
<BrowserRouter>
<div className="App">
<ul>
<li>
<Link to="/">home</Link>
</li>
<li>
<Link to="/play-game">Play Game!</Link>
</li>
</ul>
<Switch>
<Route path="/play-game" render={this.gameRoute} />
</Switch>
</div>
</BrowserRouter>
)
}
}
I'm flying in the dark here so your guidance would be much appreciated
Here's my package.json just in case:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"#types/jest": "^23.3.12",
"#types/node": "^10.12.18",
"#types/react": "^16.7.18",
"#types/react-dom": "^16.0.11",
"#types/react-router": "^4.4.3",
"#types/react-router-dom": "^4.3.1",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-router-dom": "^4.3.1",
"react-scripts": "2.1.3",
"typescript": "^3.2.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"tslint-check": "tslint-config-prettier-check ./tslint.json",
"lint": "tslint -c tslint.json src/**/*.{ts,tsx} --fix --format verbose"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"devDependencies": {
"tslint": "^5.12.1",
"tslint-config-prettier": "^1.17.0",
"tslint-plugin-prettier": "^2.0.1",
"tslint-react": "^3.6.0"
}
}