Why is my component not effectively receiving props? - reactjs

I keep getting a message that the item I'm trying to access via props is undefined. Can you please tell me why it's not working?
Here is where the instance where the props are attempting to be passed... I'm specifically talking about the tellus and yourTrial props.
import React from 'react'
import Info from './components/Info'
import Upsell from '../../../general/components/order/components/Upsell'
import FormTwo from '../../../general/components/forms/FormTwo'
import Footer from '../../../cbd-desktop/components/layout/Footer'
export default class Order extends React.Component {
render() {
return (
<div>
<div>
<div style={styles.header}>
<img style={styles.leaf} src="./resources/desktop-img/leaves_top.png" />
<img style={styles.logo} src="./resources/desktop-img/logo_white.png" />
</div>
<div style={styles.wrapper}>
<div style={styles.leftWrapper}>
<Info />
<Upsell styles={upsellStyles} />
</div>
<FormTwo styles={formStyles} tellus="Tell us where to send" yourTrial="YOUR TRIAL BOTTLE"} />
</div>
</div>
<Footer style={styles.footer}/>
</div>
)
}
}
And here is where I am trying to display these values on the child... towards the top in two h2s
import React from 'react'
import { connect } from 'react-redux'
import { stepTwoSubmit, saveBillingData } from
'../../actions/formStepTwoActions'
import { addReceiptProduct } from '../../actions/receiptActions'
import FormTwoInputs from './components/FormTwoInputsComponent.jsx'
import Throbber from '../throbber/Throbber'
import FormWarning from './components/FormWarningComponent.jsx'
import Button from '../../../cbd-desktop/components/layout/Button'
const mapStateToProps = state => ({
state:state,
config:state.config,
downsellProduct:state.downsell.downsellProduct || {},
receiptProducts:state.receipt.receiptProducts || []
})
const mapDispatchToProps = {
stepTwoSubmit,
saveBillingData,
addReceiptProduct
}
#connect(mapStateToProps, mapDispatchToProps)
export default class FormTwo extends React.Component {
constructor(props) {
super(props)
componentWillReceiveProps(nextProps) {
let formTwoResponse = nextProps.state.stepTwo.formTwoResponse
this.checkOrderStatus(formTwoResponse)
}
componentDidMount() {
this.fillMainOrder()
this.calculateViewers()
this.calculateTimer()
}
render() {
let { state, props, inputs, onInputFocus, saveInputVal, styles } = this,
CustomTag = props.labels ? 'label' : 'span',
{ submitting, formWarning } = state,
{ invalidInputID, text, visible } = formWarning
return (
<div style={styles.formWrapper}>
<p style={styles.yellowBanner}>{this.state.viewers} people viewing this product right now</p>
<div style={styles.formInnerWrapper}>
<div style={styles.headerWrapper}>
<h2 style={styles.header}>{this.props.tellus}</h2>
<h2 style={styles.header}>{this.props.yourTrial}</h2>
</div>
<div style={styles.weAccept}>
<p style={styles.weAcceptText}>We Accept:</p>
<img style ={styles.cardImage} src="resources/desktop-img/cards.png" />
</div>
<form onSubmit={this.submit}>
<FormTwoInputs onInputFocus={onInputFocus} saveInputVal={saveInputVal} CustomTag={CustomTag} styles={styles} />
<FormWarning visible={visible} invalidInputID={invalidInputID} text={text} />
<Button style={styles.button} buttonText="RUSH MY TRIAL" />
</form>
</div>
<img src="resources/desktop-img/secure.png" />
<div style={styles.urgencyWrapper}>
<div style={styles.urgencyTextWrapper}>
<span style={styles.redText}>{this.state.viewers} people are viewing this offer right now -</span>
<span style={styles.blueText}>{this.state.counter}</span>
</div>
<p style={styles.blueText}>Claim Your Bottle Now</p>
</div>
<Throbber throbberText='Confirming your shipment...' showThrobber={submitting} />
</div>
)
}
}

Related

React render button 'x' of times

I have a switch button that I want to copy ten times but when I copy the button to new div it does not let me click on second button onwards, I can change state of one first button only. Here is my code
class App extends Component {
handleSwitch = e => console.log(e.target.checked);
render() {
return (
<div>
<div>
<p className="title">source</p>
<label className="label">Button</label>2
<SwitchButton
onChange={this.handleSwitch}
title="SwitchButton"
data-name="vd"
/>
</div>
<div>
<label className="label">Button2</label>
<SwitchButton
onChange={this.handleSwitch}
title="SwitchButton2"
data-name="vd1"
/>
</div>
</div>
);
}
}
here is my live demo : https://stackblitz.com/edit/react-ts-9n4lwa?file=index.tsx
You should set a unique switchButtonID in each SwitchButton
import React, { Component } from 'react';
import { render } from 'react-dom';
import SwitchButton from './Hello';
import './style.scss';
class App extends Component {
handleSwitch = e => console.log(e.target.checked);
render() {
return (
<div>
<div>
<p className="title">Precursor source</p>
<label className="label">Ch1_PulsingValveActivationlnSw</label>
<SwitchButton
switchButtonID={1}
onChange={this.handleSwitch}
title="SwitchButton"
data-name="vd"
/>
</div>
<div>
<label className="label">Ch1_PulsingValveActivationlnSw</label>
<SwitchButton
switchButtonID={2}
onChange={this.handleSwitch}
title="SwitchButton2"
data-name="vd1"
/>
</div>
</div>
);
}
}
render(<App />, document.getElementById('root'));

React undefined props issues

Hello I have a question about my code.
In the SearchBar.js, I got error, which is undefined props.
I have two question, if it is undefined why the if statement does not invoke and
I don't understand why props is undefined because I think I pass props properly from parent component to child component( SearchBar.js)
enter code here
import React from 'react';
import ReactDOM from 'react-dom';
import SearchBar from './components/SearchBar';
import ShopList from './components/ShopList';
class App extends React.Component {
state ={ title: [], text: ''}
componentDidMount(){
this.setState({title:["javascript","react","redux","c++","java"]})
}
handleSubmit = (e) =>{
e.preventDefault();
}
handleChange = (e) => {
this.setState({text: e.target.value})
}
render() {
return (
<div>
<div className="split left">
<div className="centered">
<SearchBar handleSubmit={this.handleSubmit} handleChange={this.handleChange} userinput={this.state.text}/>
<ShopList shops={this.state.title}/>
</div>
</div>
<div className="split right">
<div className="centered">
</div>
</div>
</div>
)
}
}
ReactDOM.render(<App />, document.querySelector('#root'));
SearchBar.js
import React from 'react';
class SearchBar extends React.Component{
constructor(props){
super(props);
}
render(){
if(!this.props){
return <div>Loding..</div>
}
return (
<form className="ui form" onSubmit={this.props.handleSubmit}>
<div className="inline field">
<input onChange={this.props.handleChange} className="myinput" type="text" style={{width: '85%'}} value={props.userinput}/>
<button className="ui primary button" type="submit">button</button>
</div>
</form>
)
}
}
export default SearchBar;

How to render another page onclick

I'm using Reactjs. I want to render another page on the same place where main page is render. Below is code for my app.js file.
import React, { Component } from 'react';
import Online from './components/userview';
import Login from './components/login';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.handleLogin = this.handleLogin.bind(this);
this.state = { LoggedIn: false };
}
handleLogin(props) {
this.setState = { LoggedIn: true };
console.log(this.setstate.LoggedIn);
}
render() {
return (
<div className="App">
<div className="header col-lg-12">
<img
src={require('../src/images/logo.png')}
style={{ maxWidth: '80vh', maxHeight: '100vh' }}
/>
</div>
<button
type="button"
class="btn btn-primary"
onClick={this.handleLogin}
>
Sign In
</button>
<button type="button" class="btn btn-info">
Join Live chat
</button>
<Login />
</div>
);
}
}
export default App;
and here is the page which I want to render at the place to app.js.
import React, { Component } from 'react';
export default class Login extends Component {
render() {
return (
<div className="login">
<form>
<div>
<label>Your ID:</label>
<input type="text" ref="id" />
</div>
<br />
<br />
<input type="submit" value="submit" />
</form>
</div>
);
}
}
How to render this page when I click on login button?
In your App render method, you can do :
if(this.state.LoggedIn) return <Login />
Add the below code inside the App component's render method.
render(){
if(this.state.LoggedIn)
return <Login />;
else {
return(
<div className="App">
....
</div>
);
}
}
Check the working code on CodeSandbox

Pass map's argument to function in ReactJS

I am trying to make a todoList by ReactJS. I want to delete an item by its id, but when I console.log(id), it returns undefined. Here is my code
App.js:
import React, { Component } from 'react';
import './App.css';
import Header from './Components/header';
import InputTodo from './Components/todoInput';
class App extends Component {
constructor(props){
super(props);
this.state={
todos:[
{id:0,text:'Make dinner'},
{id:1,text:'Fold the laundary'},
{id:2,text:'Do homework'}
]
}
}
addHere=(text)=>{
this.setState({
todos:this.state.todos.concat([text])
})
}
removeHere=(id)=>{
console.log(id);
// let arr=this.state.todos;
// let index=arr.findIndex((x)=>x.id===id);
// console.log(index);
}
render() {
return (
<div className='todo-wrapper'>
<Header/>
<InputTodo todoText='Type Here...' addTodo={this.addHere}/>
<div>
{this.state.todos.map((value,key)=>{
return (
<div className='row myList' key={key}>
<p className='col-xs-10'> {value.text}-{value.id} </p>
<button className='btn btn-danger pull-right col-xs-2' onClick={this.removeHere(value.id)}>Delete</button>
</div>
)})}
</div>
</div>
);
}
}
export default App;
The following is InputTodo.js:
import React, {Component} from 'react';
import '../App.css';
export default class InputTodo extends Component{
constructor(props){
super(props);
this.state={
todoInput:{
id:2,
text:''
}
}
}
handleSubmit=(e)=>{
if(this.refs.title.value===''){
alert('You must input something');
}
else{
this.state.todoInput={
id:this.state.todoInput.id+1,
text:this.refs.title.value
};
this.setState(this.state);
this.props.addTodo(this.state.todoInput);
this.refs.title.value='';
}
e.preventDefault();
}
render(){
return(
<form className='input-group' onSubmit={this.handleSubmit}>
<input type='text' ref="title" className='form-control'placeholder={this.props.todoText}/>
<span className='input-group-btn'>
<input type='submit' value='Submit' className='btn btn-primary' />
</span>
</form>
);
}
}
While FuzzyTree's answer will work, a cleaner approach would be extracting the todo item's JSX into its own component. This would have the added benefit of not creating a new function for the button's onClick prop every time App's render function gets called.
The component might look like this:
// TodoItem
class TodoItem extends Component {
handleRemove = () => this.props.onRemove(this.props.id)
render() {
return (
<div className='row myList'>
<p className='col-xs-10'> {this.props.text}-{this.props.id} </p>
<button className='btn btn-danger pull-right col-xs-2' onClick={this.handleRemove}> Delete </button>
</div>
)
}
}
// App render
render() {
return (
<div className='todo-wrapper'>
<Header/>
<InputTodo todoText='Type Here...' addTodo={this.addHere}/>
<div>
{this.state.todos.map(({ id, text }, key) =>
<TodoItem key={key} id={id} text={text} onRemove={this.removeHere} />
)}
</div>
</div>
);
}

Redux: re-rendering children on store state update

I have started to learn react + redux recently. Prior to that I have not had experience with this sort of stack.
So I ran into a problem where I do not understand why child components do not get re-rendered when reducer returns new state.
Full code on GITHUB
This is my parent component source on git:
import React from "react"
import {connect} from "react-redux"
import {fetchWarehouses} from "../../actions/warehouseActions"
import WarehouseMenu from "./WarehouseMenu"
import WarehouseView from "./WarehouseView"
import WarehouseEdit from "./WarehouseEdit"
#connect((store) => {
return {
warehouses: store.warehouses.warehouses,
selectedWarehouse: store.warehouses.selectedWarehouse,
isSelected: store.warehouses.isSelected,
warehouseCount: store.warehouses.warehouseCount,
}
})
export default class WarehousePage extends React.Component {
componentWillMount() {
this.props.dispatch(fetchWarehouses())
}
render() {
return (
<div className="container-fluid">
<div className="row">
<div className="col-sm-2">
Warehouses ({this.props.warehouseCount}):
</div>
<div className="col-sm-10">
<WarehouseMenu warehouseList={this.props.warehouses} />
</div>
</div>
<div className="col-lg-12">
<WarehouseView test={this.props.isSelected} selectedWarehouse={this.props.selectedWarehouse} />
</div>
<div className="col-lg-12">
<WarehouseEdit />
</div>
</div>
)
}
}
And these are children source on git:
import React from "react"
import store from "../../store"
import {fetchOne} from "../../actions/warehouseActions"
export default class WarehouseMenu extends React.Component {
constructor(props) {
super(props)
}
select(id) {
store.dispatch(fetchOne(id))
}
render() {
const {warehouseList} = this.props.warehouseList
if (!warehouseList) {
return <button className="btn btn-success" key="new_warehouse">+</button>
}
const mappedWarehouses = warehouseList.map(wh => <button onClick={this.select.bind(this, wh.id)} className="btn btn-default" key={wh.id}>{wh.name}</button>)
mappedWarehouses.push(<button className="btn btn-success" key="new_warehouse">+</button>)
return (
<div className="btn-group">
{mappedWarehouses}
</div>
)
}
}
And source on git:
import React from "react"
import store from "../../store"
import {deleteWarehouse, fetchWarehouses} from "../../actions/warehouseActions"
export default class WarehouseView extends React.Component {
constructor(props) {
super(props)
}
render() {
const {test, selectedWarehouse} = this.props
if (!test) {
return null
}
return (
<div className="container-fluid">
<div className="row">
<div className="col-sm-2">
ID
</div>
<div className="col-sm-10">
{selectedWarehouse.id}
</div>
</div>
<div className="row">
<div className="col-sm-2">
Name
</div>
<div className="col-sm-10">
{selectedWarehouse.name}
</div>
</div>
<div className="row">
<div className="col-sm-12">
<button className="btn btn-warning">EDIT</button>
<button onClick={this.deleteWarehouse.bind(this, selectedWarehouse.id)} className="btn btn-danger">DELETE</button>
</div>
</div>
</div>
)
}
deleteWarehouse(id) {
store.dispatch(deleteWarehouse(id))
}
}
So whenever I dispatch deleteWarehouse I want WarehouseMenu to rerender since the state of store.warehouses.warehouses changes. I do not get the expected result. Only WarehousePage rerenders (e.g. store.warehouses.warehouseCount). I've tried #connectint store to child components but did not seem to get the desired result also.
You are not alterning the warehouses property inside your warehouseReducers.js when a DELETE_WAREHOUSE_FULFILLED action is dispatched, but you do alter the warehouseCount
Your delete action:
export function deleteWarehouse(id) {
return function (dispatch) {
axios.delete(`/api/sandy/api/warehouses/${id}`)
.then((response) => {
dispatch({
type: "DELETE_WAREHOUSE_FULFILLED",
payload: null
})
})
.catch((err) => {
})
}
}
never updates the state to remove the deleted warehouse from the state.warehouses array in warehouseReducers.js:
case "DELETE_WAREHOUSE_FULFILLED": {
return {...state,
selectedWarehouse: null,
isSelected: false,
warehouseCount: state.warehouseCount - 1
}
}

Resources