I'm defining react component to connect with redux . I have the app and list components
App.js
import React, { Component } from 'react';
//import Login from './components/Login';
import List from './components/List';
import './App.css';
class App extends Component {
render() {
return ( <List />); } }
export default App;
List.js
import React from 'react';
import { connect } from 'react-redux';
const mapStateToProps= state =>{
return { articles :state.articles};
}
const connectedList = ({ articles }) =>(
{articles.map(e=>( //////**1) here I get red under the dot(.) ie., error**
<li key={e.id}>{e.title}</li>
))}
);
const List= connect(mapStateToProps)(connectedList);
export default List;
why do 1) here I get red under the dot(.) ie., error
I have exported List but I'm thrown this error
Attempted import error: './components/List' does not contain a default export (imported as 'List').
Actually I'm newbie to redux so Please explain lemme know where i'm going wrong?
Remove curly brace:
const connectedList = ({ articles }) =>(
articles.map(e=>( // implicit return
<li key={e.id}>{e.title}</li>
)
));
Or, using curly brace:
const connectedList = ({ articles }) => { // no parentheses
return articles.map(e=>( // explicitly use return
<li key={e.id}>{e.title}</li>
)
});
Using curly brace in parentheses indicates that you're returning an object. But articles.map... is obviously not an object rather looping through an object.
Related
I'm currently using the Typescript version of reactjs and keep getting the error "message is not defined".
This error is coming from line 5.
import './App.css'
import * as React from "react";
const MyComponent: React.FC = ({ message: string }) => {
return <h1>{message}</h1>
}
export default function App() {
return (
<div className="app">
<MyComponent message="hello world"></MyComponent>
</div>
);
}
You may have to typecheck your component so it knows to expect message as a parameter! Please see the following post for some more context: https://fettblog.eu/typescript-react/components/. Here is a quick solution that might help!
import './App.css'
import * as React from "react";
type MyComponentProps = {
message: string
}
const MyComponent: React.FC = ({ message }: MyComponentProps) => {
return <h1>{message}</h1>
}
I'm using a react context to manage a large input form, and I want the provider to be placed just around that input form. But it throws the following error: "A context consumer was rendered with multiple children, or a child that isn't a function. A context consumer expects a single child that is a function. If you did pass a function, make sure there is no trailing or leading whitespace around it." This is my context:
import React from "react";
import { useState } from "react";
const AddHeaderContext = React.createContext({
headerType: "",
})
export const AddHeaderContextProvider = (props) => {
const [headerType, setHeaderType] = useState("noimage")
const headerTypeChangeHandler = (type) => {
setHeaderType(type)
}
const contextValue = {
headerType: headerType,
}
return (
<AddHeaderContext.Provider value={contextValue}>
{props.children}
</AddHeaderContext.Provider>
)
}
export default AddHeaderContext
This is when there is an error:
import AddHeaderContextProvider from './store/AddHeaderContext'
<AddHeaderContextProvider>
<AddHeaderSection />
</AddHeaderContextProvider>
But weirdly the error disappears when I move the context up into my index.js top level element and wrap everything in it.
Any idea why that could be? Also, I tap into this context usinig "useContext" hooks and not .Consumer.
I figured it out:
I just needed to use curly brackets around the contextProvider since it wasn't the main export from that file:
import { AddHeaderContextProvider } from './store/AddHeaderContext'
<AddHeaderContextProvider>
<AddHeaderSection />
</AddHeaderContextProvider>
You have this export default AddHeaderContext in AddHeaderContext.js, so when you do import AddHeaderContextProvider from './store/AddHeaderContext'
you are actually getting AddHeaderContext (the default export), not AddHeaderContextProvider.
Either change your import to import {AddHeaderContextProvider} from './store/AddHeaderContext' or your exports as below:
import React from "react";
import { useState } from "react";
export const AddHeaderContext = React.createContext({
headerType: "",
});
const AddHeaderContextProvider = (props) => {
const [headerType, setHeaderType] = useState("noimage");
const headerTypeChangeHandler = (type) => {
setHeaderType(type);
};
const contextValue = {
headerType: headerType,
};
return (
<AddHeaderContext.Provider value={contextValue}>{props.children}</AddHeaderContext.Provider>
);
};
export default AddHeaderContextProvider;
I want a link in the but then i dont know how to i use it with const
with class it works. can anyone please explain about const components
import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
const mapStateToProps= state =>{
return { articles :state.articles};
}
const connectedList = ({ articles }) =>(
articles.map(e=>(
<li key={e.id}>{e.title}</li>
))
<Link to="/Form">Form</Link>//// this line is error thrown
);
const List= connect(mapStateToProps)(connectedList);
export default List;
I know I'm do it the wrong way as i have no idea how do i achieve it the right way
You have some syntax errors. Most importantly, your "connectedList" didn't actually return/render anything.
You would have run into other problems because you hadn't wrapped your array of <li>s into a <ul>, but also, a React component render expects there to be only a single element at the top-level -- which is why I wrapped everything in a <div>.
I've cleaned up some items for clarity and used a React class instead of a functional component:
import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
class List extends React.Component {
render() {
const { articles } = this.props
const articleListItems = articles.map(article => {
return <li key={article.id}>{article.title}</li>
})
return (
<div>
<ul>
{articleListItems}
</ul>
<Link to="/Form">Form</Link>
</div>
)
}
}
const mapStateToProps = state => {
return {
articles: state.articles
}
}
const ListContainer = connect(mapStateToProps, null)(List)
export default ListContainer
I'm trying to learn some redux. Component I'm working on is a simble <div> based button that - when clicked - passes value as a parameter to the dispatch, so it can be displayed later someplace else.
After following both documentation and tutorials over the web I came up with the following code:
main app container
import React, { Component } from 'react'
import { Provider } from 'react-redux'
import configureStore from './../store/configureStore.js'
import Input from './input.js'
let store = configureStore()
export default class App extends Component {
render() {
return (
<Provider store={store}>
<Input />
</Provider>
)
}
}
button container
import React, { Component } from 'react'
import { connect } from 'react-redux'
import printOut from './../actions/actions.js'
import InputComponent from './../components/inputComponent.js'
import PropTypes from 'prop-types'
const mapDispatchToProps = (dispatch) => {
return {
onClick: (input) => dispatch(printOut(input))
}
}
const Input = connect(mapDispatchToProps)(InputComponent)
export default Input
button component
import React, { Component } from 'react'
import PropTypes from 'prop-types'
class Input extends Component {
render() {
return (
<div style={style} onClick={this.props.onClick('lala')}>Button!</div>
)
}
}
Input.PropTypes = {
onClick: PropTypes.func.isRequired
}
const style = {
height: 30,
width: 100,
backgroundColor: '#ff4068'
}
export default Input
Application breaks. I got this from the console:
Uncaught TypeError: (0 , _actions2.default) is not a function
at Object.onClick (index.js:33683)
at Input.render (index.js:33743)
(...)
index.js:22443 The above error occurred in the <Input> component:
in Input (created by Connect(Input))
in Connect(Input) (created by App)
in Provider (created by App)
in App
From what little I understood, there are some issues with button component and the way I'm trying to pass the param to props. So I tried to change it a little and added a function to handle that before render.
...
onClick(input) {
return this.props.onClick(input)
}
render() {
return (
<div style={style} onClick={onClick('lala')}>Button!</div>
)
}
...
The error I get this time is onClick is not defined. Oh, ok. I forgot this keyword before calling this new function. So I add it to the component and now I have
<div style={style} onClick={this.onClick('lala')}>Button!</div>
But the error being returned didn't really changed - it's again the original error of Uncaught TypeError: (0 , _actions2.default) is not a function
I'm starting to run out of ideas now. Could someone please tell me how what my be the issue here?
Help me Stack Overflow, you're my only hope! to quote timeless classic.
Are you sure you are importing printOut in properly? Shouldn't it be import { printOut } from './../actions/actions.js' ?
Then, first argument in connect is mapStateToProps and the second is mapDispatchToProps this is probably why you have dispatch is not a function.
You are importing InputComponent:
import InputComponent from './../components/inputComponent.js'
but inside button component you are exporting it as Input:
export default Input
so change InputComponent with :
import Input from './../components/inputComponent.js'
Use this for connect
export default connect(mapDispatchToProps)(Input)
You are facing 2 problems.
1. Syntax problem in your import
The following problem Uncaught TypeError: (0 , _actions2.default) is not a function is caused by the import of your actions.
Instead of
import printOut from './../actions/actions.js'
It should be
import { printOut } from './../actions/actions.js'
2. You are incorrectly using connect
connect accepts these two arguments with the following order:
mapStateToProps: contains the props you want to give to the component
mapDispatchToProps: contains the actions to dispatch
Even if you could call your action, there is no way the dispatch will happen because you call the reducers instead of the dispatch.
What you should do is the following:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { printOut } from './../actions/actions.js';
import InputComponent from './../components/inputComponent.js';
import PropTypes from 'prop-types';
const mapDispatchToProps = (dispatch) => {
return {
onClick: (input) => dispatch(printOut(input))
}
}
export default connect(null, mapDispatchToProps)(InputComponent);
You can read this documentation for more details: http://redux.js.org/docs/basics/UsageWithReact.html#implementing-container-components
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.