How to pass a value between 2 components? - javascript

I have 2 separate components, Form component is the step 1 where you enter your name, then by clicking <Link /> you go to the next step which is Welcome component.
How can I pass the name value {this.state.value} from Form component to Welcome component so it can retrieve what was typed in the Form component.
Form component:
import React from 'react';
import Link from 'react-router';
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
}
render() {
return (
<div className='root'>
<p>Setup the engine analysation presentation to demo incubation functionality.</p>
<div className='fieldRow'>
Name
<input type="text" autoFocus value={this.state.value} placeholder='Enter Name...' />
</div>
<div className='btnWrapper'>
<Link to='/welcome' >Access Demo</Link>
</div>
</div>
);
}
}
export default Form
Welcome component:
import React from 'react';
class Welcome extends React.Component {
render() {
return (
<div className='root'>
Welcome <!-- Name Input from Form component -->
</div>
);
}
}
export default Welcome;

You can pass it as state like this
<Link to={{
pathname: '/welcome',
state: {
name: this.state.value
}
}}>Access Demo</Link>
Then get it on welcome page (component) using withRouter
const { location } = this.props;
const name = location && location.state && location.state.name;

Related

How to update react component state from one component to another, and call any functions from any component

I am very new to react, when I put everything in one place, it works fine. But when I split it into components, everything went wrong.
I have two files App.js and Activity1.js
Activity1.js contains an input with an event handler attached to it. This input is simply wrapped inside a div.
The input was initially in App.js but I extracted it to Activity.js.
The input has a sibling, a div where I echo whatever the user types in the input, by updating the props state. How can I update the state. Your time and interest is appreciated.
Here's my code:
App.js
import './App.css';
import React from 'react';
import Activity1 from './f/Activity1';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {value:15};
}
checkInput = e => {
this.setState({value: e.target.value});
}
render(){
return (
<div className="p-2">
<div>
<Activity1 />
</div>
</div>
)
}
}
export default App;
Here's Activity1.js
import React from "react";
class Activity1 extends React.Component{
constructor(props){
super(props);
}
render(){
return (
<div>
<div>Enter Number</div>
<input className="form-control" onChange={this.checkInput} />
<div className="p-2 mt-3">{this.state.value}</div>
</div>
)
}
}
export default Activity1;
Hope this solves the problem.
app.js
...
<Activity1 checkInput = {this.checkInput} inputValue = {this.state.value}/>
...
Activity1.js
...
render() {
const {checkInput, inputValue} = this.props;
...
<input className = "form-control" onChange = {checkInput} />
<div className = "p-2 mt-3"> {inputValue} </div>
You can pass a function as a prop to the other component.
<div>
<Activity1 checkInput={this.checkInput} inputValue = {this.state.value}/>
</div>
In your Activity1 component,
const {checkInput, inputValue} = this.props;
onChangeEventHandler= () => {
checkInput();
}
and
<input className = "form-control" onChange = ={this.onChangeEventHandler} />
<div className = "p-2 mt-3"> {this.inputValue} </div>
https://dev.to/vadims4/passing-down-functions-in-react-4618
You can use a Callback function
<Activity checkInput = {this.checkInput} inputValue = {this.checkInput.bind(this)}/>

How to get label values dynamically and adding the numbers together from different input with reactjs

Created a Div and inside it I have label element and input element, I want to get different label values in each div. How to re-use my div component
instead of coding the same code again.
I have tried to search in Stackoverflow plus googles, Haven't received a better answer.
Here I have created div element with just label and input element and then I have rendured this component in App.js file:
How can I reuse the same code/component to create 2 more div and having different labels values in it? Ho can I add numbers together from different input ( which I am getting from different components input)
Appreciate all your help!
import React, { Component } from 'react';
import './calculator.css';
class Boxes extends Component {
state = {
inputOne: '',
inputtwo: '',
inputthree: ''
}
getInputValue = (e) => {
const value = e.target.value;
console.log('value: ', value);
this.setState({
inputOne: Number(e.target.value)
});
}
render() {
const { value } = this.props // destructuring
const {inputOne, inputtwo, inputthree } = this.state
return (
<div className="boxes">
<label className="boxeslevel" htmlFor="text">
{value}
</label>
<input
name="text"
type="text"
onChange={this.getInputValue}
/>
</div>
);
}
}
export default Boxes;
import React, { Component } from 'react';
import './App.css';
import Boxes from './components/calculator';
class App extends Component {
render(){
return (
<div className="wrapper">
<Boxes value= {"Value 1:"} onChange={this.props.onChange}/>
<Boxes value= {"Value 2:"} onChange={this.props.onChange}/>
<Boxes value= {"Value 3:"} onChange={this.props.onChange}/>
<ShowResult />
</div>
);
}
}
export default App;
You should pass a prop to your componente to be reuse. As you notice you are using local component state in your component, like const {value} = this.state try the same approach but with props like const {value} = this.props and then passing that prop in the component usage like
<Boxes value={“label 1”}/>
<Boxes value={“label 2”}/>
That would work. Hope it help you
Remember you can use as many props you need and access them as the same way mention above
You can do something like this:
class Boxes extends Component {
render() {
const { value } = this.props // value coming from props
return (
<div className="wrapper">
<div className="firstBox">
<label htmlFor="text">
{value}
</label>
<input name="text" type="text" />
</div>
</div >
);
}
}
export default Boxes;
and in your app component something like this:
import React, { Component } from 'react';
import './App.css';
import Boxes from './components/calculator';
class App extends Component {
render(){
return (
<div className="App">
<Boxes value={1}/>
<Boxes value={2}/>
<Boxes value={3}/>
</div>
);
}
}
export default App;
Here is live demo link
You have to use props instead of state in your Boxes component. Then you can pass the required props from the App component.
App.js
import React, { Component } from 'react';
import './App.css';
import Boxes from './components/calculator';
class App extends Component {
render(){
return (
<div className="App">
<Boxes value={"Value 1"}/>
<Boxes value={"Value 2"}/>
<Boxes value={"Value 3"}/>
</div>
);
}
}
export default App;
Boxes.js
import React, { Component } from 'react';
import './calculator.css';
class Boxes extends Component {
render() {
const { value } = this.props // destructuring
return (
<div className="wrapper">
<div className="firstBox">
<label htmlFor="text">
{value}
</label>
<input name="text" type="text" />
</div>
</div >
);
}
}
export default Boxes;

React state does not change

Hello I'm trying to change the state when I click the button and only when the state changes run createBattle() but the state does not change after I click the button.
At the beginning I set the state to false. The button is in Form.js with an event onClick={this.handleClick}. Then the event handleClick should set the state to true and when the state changes createBattle() in Battle.js should render the table.
Please tell me what am I doing wrong ?
Thanks
App.js
import React from "react";
import Titles from "./Components/Title";
import Form from "./Components/Form";
import Battle from "./Components/Battle";
import "./App.css";
class App extends React.Component{
state = {
startPosition : false
}
render(){
return(
<div>
<header>
<div className="meniu"></div>
</header>
<div className="wrapper">
<div className="main">
<div className="container">
<div className="title-container">
<Titles />
<div className="info">
<Form startPosition={this.state.startPosition} />
</div>
</div>
<div className="form-container">
<Battle startPosition={this.state.startPosition}/>
</div>
</div>
</div>
</div>
</div>
);
}
};
export default App;
Battle.js
import React, {Component} from "react";
import Square from "./Square";
class Battle extends Component{
constructor(){
super();
}
createBattle = () => {
let table=[];
for (let i=1; i<=10; i++){
let children = [];
for (let j=1; j<=10; j++){
children.push(<Square />)
}
table.push(<div className="board-row">{children}</div>)
}
return table;
}
render(){
console.log(this.props);
return(
<div className="center">
{this.startPosition && this.props.createBattle()}
</div>
);
}
}
export default Battle;
Form.js
import React from "react";
class Form extends React.Component{
constructor(){
super();
}
handleClick = () =>{
this.setState({
startPosition: true
});
};
render(){
console.log(this.props);
return(
<div>
<button className="button" onClick={this.handleClick}>START</button>
</div>
);
}
};
export default Form;
The state and props of a given component is not shared across other components.
If you need to communicate between components you mostly have 2 different options :
Move state logic to a common parent and pass this state as props in child components (Note that you may also need to pass some functions to allow to interact with this parent state from the child components)
Use a common state, with a framework like Redux (widely used in complex projects)
React does not support sharing of state or props values.
So you should use any of the following
React Redux
AsyncStorage

React Hight Order Component - Can not use child components in enhanced component

I am trying to implement a Higher Order Component in my react app. I have a base form component with all general login, & then I made a ContactForm component which wraps this general component.
The issue is my page become unresponsive & give maximum stack exceeded error when I try to run it. After some research I found that the issue is calling some custom components in render method of general form component. But that is the same syntax I use everywhere in app.
Why react cause this issue & how to resolve it, Am I implementing the HOC logic in wrong way? I need to import those components in the Form since they handle some logic by themselves & help to separate concerns.
Below is code for both general & HOC component.
Contact Form Component
import React, { Component } from 'react'
import Form from './form'
const createForm = FormComponent =>
class extends Component {
render() {
return <FormComponent {...this.props} />
}
}
const ContactForm = createForm(Form)
export default ContactForm
Base Form Component
import React, { Component } from 'react'
import InputText from './input-text'
import SubmitButton from './submit'
class Form extends Component {
render() {
return (
<div className="page-form">
<div className="page-form-fields clearfix">
<InputText/>
</div>
<SubmitButton />
</div>
)
}
}
export default Form
Input Text
class InputText extends Component {
render() {
const { type, icon, label, name, placeholder, maxlength, value, disabled, error, errorText } = this.props
return (
<div className={`finput ${label && 'labeled'} ${error ? 'has-error' : ''}`}>
<input
type={type || 'text'}
name={name}
className={`textfield w-input ${error ? 'has-error' : ''}`}
maxLength={maxlength}
placeholder={placeholder}
value={value}
disabled={disabled}
onChange={e => this.props.onChange(e)}
onBlur={e => this.props.onBlur && this.props.onBlur(e)}
/>
<label className="fip-label">
{label}
</label>
{error &&
<span className={`fip-info ${error && 'error'}`}>
{errorText}
</span>}
{icon && <i className={`icon icon-${icon}`} />}
</div>
)
}
}
Submit Button
import React, { Component } from 'react'
class SubmitButton extends Component {
render() {
const { response, pending } = this.props
return (
<div className="page-form-submit tright half-top-margin">
{response &&
<h4>
{response}
</h4>}
<button type="button" className="btn" onClick={e => this.props.onSubmit()} disabled={pending}>
Submit
</button>
</div>
)
}
}
export default SubmitButton
It runs fine here,
const {Component} = React
class Form extends Component {
render() {
return (
<div className="page-form">
<div className="page-form-fields clearfix">
<input type="text" />
</div>
<button>Submit</button>
</div>
)
}
}
const createForm = FormComponent =>
class extends Component {
render() {
return <FormComponent {...this.props} />
}
}
const ContactForm = createForm(Form)
ReactDOM.render(<ContactForm />, document.getElementById("app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

How to make/access state using props in react?

I made an app with multiple components and want their state to be accessed using parent/main app, I'm not sure how to get it. what i'm trying to do is when i change state in main "App" the component state should change. One of the component is 'checkbox' and now i want to access its state using parent app, I made multiple attempts but not getting it done. my code goes like this..
This is Main 'App' code:
import React, { Component } from 'react';
import Checkbox from './checkbox';
import Radio from './Radio';
import ToggleSwitch from './ToggleSwitch';
import PrimaryButton from './PrimaryButton';
class App extends Component {
onClick(isClicked){
isChecked:true
};
render() {
return (
<div id="form">
<Checkbox
onClick={this.onClick}
/>
<RadioButton
onClick={this.onClick}
/>
</div>
);
}
}
export default App;
The component i want to access goes like this:
import React, { Component } from 'react';
class Checkbox extends Component {
constructor(props){
super(props);
this.state={
isChecked:true
};
};
onCheck(){
this.setState({
isChecked: !this.state.isChecked
});
this.props.isClicked()
};
render() {
return (
<div>
<div
className={this.state.isChecked ? 'checked': 'unchecked'}
onClick={this.onCheck.bind(this)}
>
</div>
</div>
);
}
}
export default Checkbox;
You forgot to bind the onClick event in the app component, try this it will work :
class App extends Component {
onClick(isClicked){
console.log('isClicked', isClicked);
};
render() {
return (
<div id="form">
<Checkbox onClick={this.onClick.bind(this)}/>
</div>
);
}
}
If you already have onClick handler for the Checkbox I don't see why you couldn't just move the state up to the App component and just pass down a callback from there to the Checkbox that will update the parent state. That seems like a more React way to do it, to me.
class App extends Component {
constructor(props){
super(props);
this.state={
isChecked:true
}
}
onClick = (isClicked) => {
this.setState({isChecked: !this.state.isChecked})
}
render() {
return (
<div id="form">
<Checkbox
onClick={this.onClick}
ischecked={this.state.isChecked}
/>
</div>
);
}
}
Component
class Checkbox extends Component {
onCheck(){
this.props.onClick()
}
render() {
return (
<div>
<div
className={this.props.isChecked ? 'checked': 'unchecked'}
onClick={this.onCheck.bind(this)}
>
</div>
</div>
)
}
}

Categories

Resources