I have the following Parent component:
export class Parent extends Component {
constructor(props) {
super(props)
state = {
value: 0
}
}
}
render() {
return (
<Child />
)
}
And the following Child component:
export class Parent extends Component {
constructor(props) {
super(props)
state = {
num: 0
}
}
}
toggleCheckboxChange = () => {
this.setState({ num: 5})
}
render() {
return (
<div>
<label>
{this.state.num}
<input type="checkbox" onChange={this.toggleCheckboxChange}
/>
</label>
</div>
)
}
I want to use the checkbox to set the Child state num to 5, and then pass that to the Parent's state value.
What would be the best way of doing that?
As I said in my comment, it's easiest if you move the state into the parent.
working example
import React, {Component} from 'react';
import {render} from 'react-dom';
class Parent extends Component {
state = {
value: 0
}
toggleCheckboxChange = ev => {
this.setState({value: 5})
}
render() {
return (
<Child num={this.state.value} toggleCheckboxChange={this.toggleCheckboxChange}/>
);
}
}
function Child({num, toggleCheckboxChange}) {
return (
<div>
<label>
{num}
<input type="checkbox" onChange={toggleCheckboxChange}
/>
</label>
</div>
)
}
render(<Parent/>, document.getElementById('root'));
Related
I'm trying to change the state the a child component but don't change, this is the parent component:
export default class History extends Component {
constructor(props) {
super(props);
this.state = {
histories : JSON.parse(JSON.stringify(histories)),
counter: 1,
id: ''
}
}
increaseCounter = () => {
this.setState({counter: this.state.counter+1})
}
showIdHistory = (id) => {
this.setState(() => {return {id:id}})
}
render() {
return (
<div className="history">
<div>
<h3 className='titleHistory'>{searchHistoryById(this.state.id,this.state.counter)}</h3>
</div>
<div className='options'>
<div className='option'>
<BottonOptionA option='A' increaseCounter={this.increaseCounter} showIdHistory={this.showIdHistory}/>
<h2>{searchOptionById('a',this.state.counter+this.state.id)}</h2>
</div>
<div className='option'>
<BottonOptionB option='B' increaseCounter={this.increaseCounter} showIdHistory={this.showIdHistory}/>
<h2>{searchOptionById('b',this.state.counter+this.state.id)}</h2>
</div>
</div>
<div className='sectionStatics'>
<SelectionBefore optionAnterior={this.state.id}/>
<reacordOfOptions option={this.state.id}/>
</div>
</div>
);
}
}
i want that the parent component pass the state to the component called SelectionBefore but when the parent child changes the state, the props of SelectionBefore still is the same
this is the component child:
import React,{Component} from 'react'
export default class SelectionBefore extends Component {
constructor(props) {
super(props)
this.state = {
optionBefore : props.optionBefore,
}
}
render() {
return (
<div >
<p> Seleccion anterior: {this.state.optionBefore}</p>
</div>
)
}
}
Try following changes :
Child component
import React,{Component} from 'react'
export default class SelectionBefore extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div >
<p> Seleccion anterior: {this.props.optionAnterior}</p>
</div>
)
}
}
I have directly used the props which is passed by parent to the child .
This means that , whenever state of parent changes , your child will rerender and the changes will be shown .
Is there any way I can push an object to the parent props from the child component?
You can pass a function from the parent to the child that can set the state of an object in the parent.
import React, { Component } from 'react';
import { render } from 'react-dom';
const Child = ({saveObj}) => (
<div
onClick={() => {
saveObj({test: "test"})
}}
>
Click to set obj
</div>
)
class App extends Component {
constructor() {
super();
this.state = {
obj : null
};
}
render() {
return (
<div>
Obj is: {JSON.stringify(this.state.obj)}
<p>
<Child saveObj={obj => {this.setState({obj})}} />
</p>
</div>
);
}
}
render(<App />, document.getElementById('root'));
Live Example: https://stackblitz.com/edit/react-snivhc
So I have a component "itemSelection" and inside of it I map through an api response like this
<div className="row">
{this.state.items.map(i => <Item name={i.name} quantity={i.quantity} />)}
</div>
Here the state of "Item" component
constructor(props){
super(props);
this.state = {
visible: false,
selected: false,
}
}
How could I pass the state of "Item" component to "itemSelection" component?
Sending data back up to your parent component should be done by using props.
Fairly common question, see this post for the long answer.
As according to me, If I understood your question you want to call the state of the child component to the parent component.
//Child.js
import s from './Child.css';
class Child extends Component {
getAlert() {
alert('clicked');
}
render() {
return (
<h1 ref="hello">Hello</h1>
);
}
}
export default withStyles(s)(Child);
//Parent.js
class Parent extends Component {
render() {
onClick() {
this.refs.child.getAlert()
}
return (
<div>
<Child ref="child" />
<button onClick={this.onClick.bind(this)}>Click</button>
</div>
);
}
}
Also, you can get the code reference from the link: https://github.com/kriasoft/react-starter-kit/issues/909
This a little tricky but Maybe, its help you solving your problem.
//Parent.js
class Parent extends Component {
component(props) {
super(props)
this.state = {
test: 'abc'
}
}
ParentFunction = (value) => {
this.state.test = value;
this.setState(this.state);
}
render() {
return (
<div>
<Child
test={this.state.test}
ParentFunction={this.ParentFunction}
/>
</div>
);
}
}
//Child.js
import s from './Child.css';
class Child extends Component {
component(props) {
super(props)
this.state = {
test: props.test
}
}
handleChange = () => {
this.state.test = event.target.value;
this.setState(this.state);
this.handleOnSave()
}
handleOnSave = () => {
this.props.ParentFunction(this.state.test);
}
render() {
return (
<div>
<input type="text" onChange={this.handleChange} />
</div>
);
}
}
export default withStyles(s)(Child);
I have build an input-field component and need to access its value from parent component. I tried something like document.getelementById(id).value, but it'll return null as value.
Parent component:
import StateBox from './StateBox.js';
import React, { Component } from 'react';
export default class AdressenListe extends Component {
render() {
let filteredAdressen = this.props.adressen.filter(
(asingle) => {
return asingle.Firma.toLowerCase().indexOf(document.getElementById('Firma').value.toLowerCase()) !== -1;
}
);
var anzahl = filteredAdressen.length;
return (
<div>
<StateBox id="Firma" />
<StateBox id="PLZ" />
<li>
</li>
</div>
);
}
}
Input-field component:
import React, {Component} from 'react';
export default class StateBox extends Component {
//constructor input field
constructor() {
super();
//equal to object
this.state = {
search: ''
};
}
updateSearch(event) {
console.log(event.target.value);
this.setState({search: event.target.value});
}
render(){
return(
<form className="StateBox">
<input type="text" value={this.state.search} onChange={this.updateSearch.bind(this)}/>
</form>
);
}
}
You can declare the state in the parent component and pass function to update that in child component
class Parent extends Component {
this.state = {
value: ''
}
changeValue = (value) => {
this.setState({value});
}
render() {
return <Child inputValue={this.state.value} changeValue={this.state.changeValue} />
}
}
class Child extends Component {
render() {
<input value={this.props.inputValue} onChange={(e) => this.props.changeValue(e.target.value)} />
}
}
If you want to access the value of a child component, you need to lift the state up and make the child component controlled, because that's the way you should code in react.
Taking your code as base:
class AdressenListe extends Component {
constructor() {
super();
this.state = {
Firma: ''
};
}
changeValue (Firma) {
this.setState({Firma});
}
render() {
let filteredAdressen = this.props.adressen.filter(
(asingle) => {
return asingle.Firma.toLowerCase().indexOf(this.state.Firma.toLowerCase()) !== -1;
}
);
return (
<div>
<StateBox inputValue={this.state.Firma} changeValue={this.changeValue.bind(this)} />
</div>
);
}
}
Note how I pass down the necessary props and the state is managed by the parent.
class StateBox extends Component {
render () {
return <input type="text" value={this.props.inputValue} onChange={(e) => this.props.changeValue(e.target.value)} />
}
}
I have three classes in my ReactJS app. Here they are :
class FirstFilter extends React.Component {
constructor() {
super();
this.state = {
val1: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
return (
<Label>
<Input type="select" value={this.state.value} onChange={this.props.handleChange}>
<option disabled selected value>Select plox</option>
<option value='Firdt'>First</option>
<option value='Second'>Second</option>
</Input>
</Label>
);
}
}
class SecondFilter extends React.Component {
constructor() {
super();
this.state = {
val2: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.val2});
}
render() {
return (
<Label>
<Input type="search" placeholder="Print somthing" value={this.state.value} onChange={this.props.handleChange}>
</Input>
</Label>
);
}
}
class Main extends React.Component {
constructor() {
super();
this.state = {
val1: '',
val2: ''
};
this.handleChangeVal1 = this.handleChangeVal1.bind(this);
this.handleChangeVal2 = this.handleChangeVal2.bind(this);
}
handleChangeUUID(event) {
this.setState({val1: event.target.value.toLowerCase()});
}
handleChangeOrigin(event) {
this.setState({val2: event.target.value.toLowerCase()});
}
render() {
return (
<div>
<Form inline>
<FormGroup>
<div>
<UuidRow handleChange = {this.handleChangeVal1} />
</div>
<div>
<OriginRow handleChange = {this.handleChangeVal2} />
</div>
</FormGroup>
</Form>
</div>
);
}
}
I want make SearchField from second filter empty when i check whatever in my DropDownList from first filter. When i only change value in my Main it's still leave typed text there. Maybe I doing something wrong and didn't understand basic hierarchy?
You should pass props to your child component, SearchField, when the state of the parent, Main, has been updated by the callback invoked by the DropDownList. The code in your example isn't consistent, so I can't guess what I need to change to help you, but here is a very basic example of how setting state in the parent via a callback event handler passed to one child (text input) can be used to set props on the second child (text area):
https://codesandbox.io/s/BLwl1y6j2
main.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import FirstChild from './FirstChild';
import SecondChild from './SecondChild';
class Main extends Component {
constructor(props) {
super(props);
this.state = {
val1: '',
};
}
// callback to pass as prop to child element text input
handleChangeVal1 = (event) => {
// sets parent state
this.setState({val1: event.target.value.toLowerCase()});
}
render() {
return (
<div>
<FirstChild handleChange = { this.handleChangeVal1 } value={ this.state.val1 }/>
<SecondChild value={ this.state.val1 }/>
</div>
);
}
}
render(<Main />, document.getElementById('root'));
FirstChild.js
import React, {Component } from 'react';
class FirstChild extends Component {
// input calls handleChange callback passed in props to modify parent component state
render() {
console.log(this.props.value);
return (
<input type="text" value={this.props.value} onChange={this.props.handleChange}/>
);
}
}
export default FirstChild;
SecondChild.js
import React, { Component } from 'react';
class SecondChild extends Component {
// render text area with value passed in props
render() {
console.log(this.props.value);
return (
<textarea value={this.props.value} onChange={this.props.handleChange}/>
);
}
}
export default SecondChild;