Pass values from one component to another in react - reactjs

container.js -
//Here we render the recipe details and display add recipe form.
import React, { Component } from 'react';
import './App.css';
import AddRecipe from './addrecipe.js';
class App extends Component {
constructor(props){
super(props);
this.state={ recipes :[] }
this.addRecipe=this.addRecipe.bind(this);
}
addRecipe (recipe) {
this.setState({
recipes: [...this.state.recipes, recipe]
});
}
componentWillMount(){
this.setState({
recipes : require('./sample-recipes')
});
}
home(e){
window.location='/a';
}
render() {
return (
<div className="App">
<h2>Welcome to the Recipe Book</h2>
<dl>
{this.state.recipes.map(recipe => {
return ( <div key={recipe.name} onClick={this.home}>
<dt>{recipe.name}</dt>
<dd>{recipe.ingredient}</dd>
<div><img src='{recipe.image}' className="image"/></div>
<hr></hr>
</div>
)
})
}
</dl>
<button className="addButton" onClick={() =>
{this.setState({ display: !this.state.display })}}>
Add Recipe
</button>
<AddRecipe addRecipe={this.addRecipe}
display={this.state.display} />
</div>
);
}
}
export default App;
In home function it directs the page to ('/recipe') that is the file store.js
import React, { Component } from 'react';
import AddRecipe from './addrecipe.js';
var StorePicker = React.createClass({
render : function() {
return (
<form className="store-selector">
<h2>{recipe.name}</h2> --->//gives error recipe is not defined.
</form>
)
}
});
export default StorePicker;
How do I display recipe.name,ingredients,image in the new page given by ('/recipe').There is another file addrecipe.js that creates a form to take the input from user.
This is my index.js file--
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import AddRecipe from './addrecipe';
import StorePicker from './store';
import App from './container'
var ReactRouter = require('react-router');
var Router = ReactRouter.Router;
var Route = ReactRouter.Route;
var Navigation = ReactRouter.Navigation;
import createHistory from 'history/createBrowserHistory'
var routes = (
<Router history={createHistory()}>
<switch>
<Route exact={true} path="/recipe" component={StorePicker} />
<Route exact={true} path="/" component={App}/>
</switch>
</Router>
);
ReactDOM.render(routes, document.getElementById('root'));

Related

Failed prop type: Invalid prop 'component' supplied to 'Route': the prop is not a valid React component

When I click button visit store, I'm getting the above error. My react version is 17.0.2 & react-dom version is 17.0.2 & react-router-dom version is 5.3.0.
Index.js file
import React from "react";
import { render } from "react-dom";
import Router from "./components/Router";
import "./css/style.css";
render(<Router />, document.querySelector("#main"));
Router.js file
import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import StorePicker from "./StorePicker";
import App from "./App";
import NotFound from "./NotFound";
const Router = () => (
<BrowserRouter>
<Switch>
<Route exact path="/" component={StorePicker} />
<Route path="/store/:storeId" component={App} />
<Route component={NotFound} />
</Switch>
</BrowserRouter>
);
export default Router;
When I console log this.myInput.value.value, I'm getting undefined. Please help.
StorePicker.js file
import { getFunName } from "../helpers";
class StorePicker extends React.Component {
myInput = React.createRef();
goToStore = (event) => {
// 1. Stop the form from submitting
event.preventDefault();
// 2. Get the text from the input
const storeName = this.myInput.value.value;
// 3. Change the page to /store/whatever user has entered
this.props.history.push(`/store/${storeName}`);
};
render() {
return (
<form className="store-selector" onSubmit={this.goToStore}>
<h2>Please enter a store name</h2>
<input
type="text"
required
ref={this.myInput}
placeholder="Store Name"
defaultValue={getFunName()}
/>
<button type="submit">Visit Store </button>
</form>
);
}
}
export default StorePicker;
This one is app.js file, And I have included component inside Route.js file.
import React from "react";
import Header from "./Header";
import Order from "./Order";
import Inventory from "./Inventory";
class App extends React.Component {
render() {
return (
<div className="catch-of-the-day">
<div className="menu">
<Header tagline="Fresh Seafood Market" age="21" />
</div>
<Order />
<Inventory />
</div>
);
}
}
export default App;
And I have created NotFound() component & included the same inside Route.js file.
const NotFound = () => (
<div>
<h2>Not Found!!!</h2>
</div>
);
export default NotFound();

Component not showing up in react router with laravel

I am new to React and I am trying to display a react route using react router dom but the matching component is not coming up. I have looked at answers from other OS questions related but no help. Here is my app.js file
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import AdminLogin from './AdminLogin';
export default class AdminApp
extends Component {
render() {
return (
<Router>
<Switch>
<div className="App">
<Route path="/" exact={true} component = {AdminLogin} />
</div>
</Switch>
</Router>
);
}
}
if (document.getElementById('app')) {
ReactDOM.render(<AdminApp />, document.getElementById('app'));
}
When i inspect my html file i get this
<div id="app">
<div class="App" location="[object Object]" computedmatch="[object Object]"></div>
</div>
this is my adminLogin component
import React, {Component} from 'react';
import {adminLogin} from './UserFunctions';
export default class AdminLogin extends Component {
constructor(){
super()
this.state = {
email: '',
password: '',
errors: {}
}
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onChange(e){
this.setState({ [e.target.name]: e.target.value })
}
onSubmit(e){
e.preventDefault;
const user = {
email : this.state.email,
password : this.state.password
}
adminLogin(user).then(res => {
if(res) {
this.props.history.push('/dashboard');
}
})
}
render(){
return (
<div className="kt-grid kt-grid--ver kt-grid--root">
<div className="kt-grid kt-grid--hor kt-grid--root kt-login>
<h1>Login Now</h1>
</div>
</div>
)
}
}
This only works if you are trying the root path (/). If you need to render this component at a subpath (e.g. /foo/bar/login), that should be defined as the route path.
<Route path="/foo/bar/login" exact={true} component = {AdminLogin} />

React Redux Store Updates - Changes Don't Update Component

I'm new to Redux, using it with React, and am in need of some help. I have a menu that when a menu item is clicked, another component needs to update some copy. I'm able to dispatch an action and have the store update. However, I can't get the child component (HeroText) to render the new store value in the store.subscribe method when the store values change. Please help and thanks!
import React, { Component } from "react";
import ReactDOM from "react-dom";
import HeroText from "../presentational/HeroText.jsx";
import bgImage from "../../../images/forest_fog.jpg";
import AnantaNavbar from "../presentational/AnantaNavbar.jsx";
import '../../../scss/hero.scss';
import store from '../../store/index';
import { connect } from "react-redux";
const mapStateToProps = state => {
return {
contact: state.contact,
heroText: state.heroText
}
}
class HeroContainer extends Component {
constructor(props)
{
super(props);
this.state = store.getState();
store.subscribe(() => {
console.log(store.getState().heroText);
this.setState({
heroText: store.getState().heroText,
})
})
}
render()
{
return (
<div id="hero-container" style={{backgroundImage: ("url(" + bgImage + ")") || ""}}>
<div className="container">
<HeroText text={this.props.heroText}>
Welcome back {this.props.contact.full_name}
</HeroText>
<AnantaNavbar></AnantaNavbar>
</div>
</div>
);
}
}
export default connect(mapStateToProps)(HeroContainer);
UPDATE
Below is my parent App Container with Provider
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { Navbar, NavbarBrand, NavbarNav, NavbarToggler, Collapse, NavItem, NavLink, Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'react-bootstrap';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import LoginContainer from '../../../js/components/container/LoginContainer.jsx';
import DashboardContainer from '../../../js/components/container/DashboardContainer.jsx';
import HomeContainer from '../../../js/components/container/DashboardContainer.jsx';
import ProfileContainer from '../../../js/components/container/ProfileContainer.jsx';
import HeroContainer from "./HeroContainer.jsx";
import '../../../scss/globals.scss';
import logo from '../../../images/logo1.png';
import { Provider } from 'react-redux';
import store from '../../store/index';
const Router = () => (
<BrowserRouter>
<Switch>
<Route exact path="/" component={LoginContainer} />
<Route exact path="/login" component={LoginContainer} />
<Route exact path="/home" component={HomeContainer} />
<React.Fragment>
<HeroContainer />
<Route path="/dashboard" component={DashboardContainer} />
<Route path="/profile" component={ProfileContainer} />
</React.Fragment>
</Switch>
</BrowserRouter>
);
class AppContainer extends Component {
constructor(props)
{
super(props);
this.state = {
};
}
componentDidMount()
{
}
render()
{
return (
<div>
<Provider store={store}>
<Router></Router>
</Provider>
</div>
);
}
}
export default AppContainer;
The default heroText in the store says "DASHBOARD". When a menu item is clicked, in this case a link to /profile, the heroText should update to "PROFILE" after updating the store.
You can see in the console that the store is changing, but the "DASHBOARD" copy is not reflecting.
RESOLVED
I got this working with the code below. Thanks for all the help!
import React, { Component } from "react";
import ReactDOM from "react-dom";
import HeroText from "../presentational/HeroText.jsx";
import bgImage from "../../../images/forest_fog.jpg";
import AnantaNavbar from "../presentational/AnantaNavbar.jsx";
import '../../../scss/hero.scss';
import store from '../../store/index';
import { connect } from "react-redux";
const mapStateToProps = state => {
return {
contact: state.contact,
heroText: state.heroText
}
}
class HeroContainer extends Component {
constructor(props)
{
super(props);
}
render()
{
return (
<div id="hero-container" style={{backgroundImage: ("url(" + bgImage + ")") || ""}}>
<div className="container">
<HeroText text={store.getState().heroText}>
Welcome back {store.getState().contact.full_name}
</HeroText>
<AnantaNavbar></AnantaNavbar>
</div>
</div>
);
}
}
export default connect(mapStateToProps)(HeroContainer);
Since you are trying to get state from Redux, there's no pointing in keeping it in local state. Plus, you don't need to use store.getState, connect already does that for you.
const mapStateToProps = state => {
return {
contact: state.contact,
heroText: state.heroText
}
}
class HeroContainer extends Component {
render() {
return (
<div id="hero-container" style={{backgroundImage: ("url(" + bgImage + ")") || ""}}>
<div className="container">
<HeroText text={this.props.heroText}>
Welcome back {this.props.contact.full_name}
</HeroText>
<AnantaNavbar></AnantaNavbar>
</div>
</div>
);
}
}
export default connect(mapStateToProps)(HeroContainer);
You also need to make sure that your app is wrapped in a provider, like this:
<Provider store={store}>
<App />
</Provider>

react-intl language switcher does not update Formattedmessage in grand-child component

So I've started using react-intl in an older react-project (don't judge please).
In index.js I change the state to the selected language:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import {
BrowserRouter as Router, Route
} from 'react-router-dom';
import * as serviceWorker from './serviceWorker';
// Data
import Landing from "./components/landing/landing";
import Login from './components/app/auth/login/Login';
import Register from './components/app/auth/register/Register';
import intlEN from 'react-intl/locale-data/en';
import intlDE from 'react-intl/locale-data/de';
import { IntlProvider, addLocaleData } from "react-intl";
import messages_en from "./translations/en.json";
import messages_de from "./translations/de.json";
addLocaleData([...intlEN, ...intlDE]);
let i18nConfig = {
locale: 'EN',
messages: messages_en
};
// App
class Root extends Component {
constructor(props) {
super(props);
this.state = { locale: "EN" }
this.onChangeLanguage = this.onChangeLanguage.bind(this);
}
onChangeLanguage(lang) {
switch (lang) {
case 'DE': i18nConfig.messages = messages_de; break;
case 'EN': i18nConfig.messages = messages_en; break;
default: i18nConfig.messages = messages_en; break;
}
this.setState({ locale: lang });
i18nConfig.locale = lang;
}
render() {
return (
<Router>
<Route exact path="/" onChangeLanguage={this.onChangeLanguage} component={Landing} />
<Route path="/login" onChangeLanguage={this.onChangeLanguage} component={Login} />
<Route path="/register" render={() => <Register onChangeLanguage={this.onChangeLanguage} />} />
</Router>
)
}
}
ReactDOM.render(
<IntlProvider locale={i18nConfig.locale} key={i18nConfig.locale} messages={i18nConfig.messages}>
<Root />
</IntlProvider>,
document.querySelector("#root")
)
So in the Register component, I provide a formatted message with a function to change the language:
import React, { Component, ProtoTypes } from 'react';
import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
class Register extends Component {
render() {
const { onChangeLanguage } = this.props
return (
<div className="container d-flex vh-100 flex-column">
<button className="btn btn-link" onClick={(param) => onChangeLanguage('EN')}>
English
</button>
<button className="btn btn-link" onClick={(param) => onChangeLanguage('DE')}>
German
</button>
<FormattedMessage id="landing.hero.title"></FormattedMessage>
</div>
)
}
}
export default Register
The problem is, sadly, it is not updating anything, the formatted message returns only the selected one at page start

list transition for react isnt showing due to an error

Im New to react.
Im trying to implement this into my react app.
https://github.com/trungdq88/react-router-page-transition/blob/master/EXAMPLES.md
Now i dont want it to show on my home page like the example but in my "MyStories" component when you navigate to that component . But it seems i did something wrong and now im recieving this error.
Uncaught Error: MyStories.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
heres my code.
import React from 'react';
import { Router, Route, browserHistory } from 'react-router';
import Layout from './components/Layout';
import Profile from './components/Profile';
import MyStories from './components/MyStories';
import NewStory from './components/NewStory';
import PageTransition from 'react-router-page-transition';
import DetailPage from './components/DetailPage';
class Root extends React.Component {
constructor(props){
super(props)
this.state = {
}
}
render() {
return(
<Router history={browserHistory}>
<Route path='/' component={Layout}>
<IndexRoute component={Layout} />
<Route path="/MyStories" component={MyStories}/>
<Route path="/profile" component={Profile}/>
<Route path="/NewStory" component={NewStory}/>
<Route path="/detail/:itemId" component={DetailPage} />
</Route>
<Route path="/detail/:itemId" component={DetailPage} />
</Router>
)
}
}
export default Root;
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import { browserHistory } from 'react-router';
import Root from './Root';
let reactAppRender = (element) => {
ReactDOM.render(
<Root browserHistory={browserHistory}/>,
element
);
};
$(function() {
let reactApp = document.getElementById('app');
if (reactApp) {
reactAppRender(reactApp);
}
});
import React from 'react'
import { Link } from 'react-router';
export default React.createClass({
render() {
return
<div className="transition-item list-page">
{this.state.items.map(item => (
<Link
key={item.id}
className="list-item"
to={`/detail/${item.id}`}
>
<Item {...item} />
</Link>
))}
</div>
}
})
import React from 'react';
import { Link } from 'react-router';
import PageTransition from 'react-router-page-transition';
class Layout extends React.Component {
constructor(props){
super(props)
this.state = {
}
}
render() {
return(
<div>
<h1>Welcome </h1>
<ul role="nav">
<li><Link to='/'>HOME</Link></li>
<li><Link to="/profile">Profile</Link></li>
<li><Link to="/mystories">MyStories</Link></li>
<li><Link to="/newstory">NewStory</Link></li>
</ul>
<PageTransition>
{this.props.children}
</PageTransition>
</div>
)
}
}
export default Layout;
import React from 'react';
import { Link } from 'react-router';
export default class DetailPage extends React.Component {
render() {
return (
<div className="transition-item detail-page">
<Link to="/">Back</Link>
<h1>
Detail {this.props.params.itemId}
</h1>
</div>
);
}
}
The component above Layout has a render() method with a return in one line, but what you want to return starts in the line below it:
import React from 'react'
import { Link } from 'react-router';
export default React.createClass({
render() {
return
<div className="transition-item list-page">
{this.state.items.map(item => (
<Link
key={item.id}
className="list-item"
to={`/detail/${item.id}`}
>
<Item {...item} />
</Link>
))}
</div>
}
})
When this happens, wrap the JSX component in parenthesis:
import React from 'react'
import { Link } from 'react-router';
export default React.createClass({
render() {
return (
<div className="transition-item list-page">
{this.state.items.map(item => ( //Incidentally, you reference this.state here but your component has no state
<Link
key={item.id}
className="list-item"
to={`/detail/${item.id}`}
>
<Item {...item} />
</Link>
))}
</div>
)
}
})
You did this in the other components, you might have just missed this one.
For the future: if you get an error along the lines of Uncaught Error: MyStories.render(): A valid React element (or null) must be returned. look at return statement of the render method of the component that the error is mentioning (in this case, MyStories). Remember, for now you can only return JSX from the render method of a React component.

Resources