Send data from child to parent React - reactjs

I don`t know where i do wrong.I cant send data from child to parent.
What is wrong here?
How can i grab the state from child and send to parent state?
this is the child component
import React from 'react';
export class Child extends React.Component{
constructor(props) {
super(props);
this.state= {
counter2: 5
}
}
render() {
return(
<div>
<button onClick={this.props.data}>Click me</button><span>{this.state.counter2}</span>
</div>
);
}
}
export default Child;
and i want to update the state in parent component
import React from 'react';
import {Child} from './Child';
export default class Parent extends React.Component{
constructor(props){
super(props);
this.state= {
counter: 0
}
}
update(){
this.setState({
counter: this.props.state.counter2
});
}
render(){
return(
<div>
<span>{this.state.counter}</span>
<Child data={this.update.bind(this)}/>
</div>
);
}
}
but i have a error:
×
TypeError: Cannot read property 'counter' of undefined?
i cant understand what i do wrong!
Thank you

Actually, you don't have state property in your Parent's props.
You can't get child's state in a such way:
this.props.state.counter2
Props ONLY passed from parent component to child (if you don't use Redux or another state management library).
Nevertheless, you can pass it like this:
Parent component
import React from 'react';
import {Child} from './Child';
export default class Parent extends React.Component{
constructor(props){
super(props);
this.state= {
counter: 0
}
}
update(value){
return () => {
this.setState({
counter: value
});
}
}
render(){
return(
<div>
<span>{this.state.counter}</span>
<Child data={this.update.bind(this)}/>
</div>
);
}
}
Child component
import React from 'react';
export class Child extends React.Component{
constructor(props) {
super(props);
this.state= {
counter2: 5
}
}
render() {
return(
<div>
<button onClick={this.props.data(this.state.counter2)}>Click me</button><span>{this.state.counter2}</span>
</div>
);
}
}
export default Child;

You are not passing content2 state in the child component correctly
You need to pass it with the button
<button onClick={()=> this.props.data(this.state.counter2)}>Click me</button><span>{this.state.counter2}</span>
Then in your update function
update = (data) =>{
this.setState({
counter: data
});
}
Note: no need to bind update function if you are using arrow function
like me.
<div>
<span>{this.state.counter}</span>
<Child data={this.update)}/>
</div>

Related

Don't change the state in my component - React

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 .

How to change title from child component to parent component without hooks?

I have two components child and parent. And I want to change the title of the parent component from the child component. But without hooks.
So I have this:
class App extends Component {
render() {
return (
<div className="app">
<ParentComponent/>
</div>
);
}
}
export default App;
and child component:
import React from 'react'
function ChildComponent(props) {
return (
<div>
<h1>Child COmponent</h1>
<button onClick={() => props.greetHandler('Niels')}>Greet parent</button>
</div>
)
}
export default ChildComponent;
and parent component:
class ParentComponent extends Component {
constructor(props) {
super(props);
this.state = {
parentName: 'parent'
};
this.greetParent = this.greetParent.bind(this);
}
greetParent(childname) {
`${childname}`;
}
render() {
return (
<div>
<h1>{this.state.parentName}</h1>
<ChildComponent greetHandler={this.greetParent} />
</div>
)
}
}
export default ParentComponent;
But nothing happens And I got the message:
./src/ParentComponent.js
Line 19: Expected an assignment or function call and instead saw an expression no-unused-expressions
So my question: what I have to change that the title of parent component will change to Niels
you should change the state in greetParent function
greetParent(childname) {
this.setState({
parentName: childname
})
}

How to get the DOM ref of a child class component in a parent class component

I'm having a hard time understanding the docs on how to access the DOM ref of a child class component from the parent class component.
Parent.js:
import Child from './Child';
class Parent extends Component {
constructor(props) {
super(props);
this.refOfTheParent = React.createRef();
}
componentDidMount() {
const parentDOM = this.refOfTheParent.current;
//const childDOM = ???;
}
render() {
return (
<div ref={this.refOfTheParent}>
<Child />
</div>
);
}
}
export default Parent;
Child.js:
class Child extends Component {
render() {
return (
<div>Child component</div>
);
}
}
export default Child;
Could someone please finish this code for me where childDOM in Parent::componentDidMount() has the DOM ref of <Child />.
Bonus: How would it look if Parent AND Child are both connected with react-redux connect.
You can use forwardRef
class Child extend React.Component{
render() {
return (
<div ref={this.props.forwardRef}> Child component </div>
)
}
}
export default React.forwardRef((props, ref) => <Child {...props} forwardRef={ref} />)
Then in parent
constructor(props) {
// ...
this.childRef = React.createRef();
}
render() {
return (
<div>
<Child ref={this.childRef} />
</div>
)
}
more info here
you can pass the ref in props in child component like
import React,{Component} from 'react';
import Child from './Child';
class Parent extends Component {
constructor(props) {
super(props);
this.refOfTheParent = React.createRef();
this.childRef=React.createRef();
}
componentDidMount() {
const parentDOM = this.refOfTheParent.current;
const childDom=this.childRef.current;
console.log(childDom);
//const childDOM = ???;
}
render() {
return (
<div ref={this.refOfTheParent}>
<Child childRef={this.childRef}/>
</div>
);
}
}
export default Parent
Child Component
import React,{Component} from 'react';
class Child extends Component {
render() {
return (
<div ref={this.props.childRef} id="1">Child component</div>
);
}
}
export default Child;
Demo

change state of Component A from onClick of component B

I want to change the state of the component A from an onClick handler of a button that is located in the component B, I currently have my code like this:
Component A:
import React, { Component } from 'react'
import ComponentB from './component_b'
class ComponentA extends Component{
constructor(props){
super(props);
this.state=({
allergies11:'',
allergies12:'',
allergies13:'',
allergies14:''
})
this.onCCDSubmit = this.onCCDSubmit.bind(this);
}
onCCDSubmit(e){
e.preventDefault()
this.setState({
allergies11:'Penicillin',
allergies12:'2/13/10',
allergies13:'Hives',
allergies14:'moderate'
})
this.on
}
render(){
return(
<div>{this.state.allergies11} {this.state.allergies12} {this.state.allergies13} {this.state.allergies14}
<ComponentB />
<div>
)
}
}
export default ComponentA;
Component B:
import React, { Component } from 'react';
class ComponentB extends Component{
render(){
return(
<button type="button" onClick={this.onCCDSubmit}>Import</button>
)
}
}
export default ComponentB;
how can i achieved this, any help is welcome!
You can pass a callback to your Component B, which would trigger the callback upon click...
Component B:
import React, { Component } from 'react';
class ComponentB extends Component{
render(){
return(
<button type="button" onClick={this.props.clickHandler}>Import</button>
)
}
}
export default ComponentB;
Component A:
import React, { Component } from 'react'
import ComponentB from './component_b'
class ComponentA extends Component{
constructor() {
super();
this.handleClickB = this.handleClickB.bind(this);
}
handleClickB(e) {
e.stopPropagation();
this.setState({
// new state you want to set...
});
}
render(){
return(
<div>{this.state.allergies11} {this.state.allergies12} {this.state.allergies13} {this.state.allergies14}
<ComponentB clickHandler={this.handleClickB} />
<div>
)
}
}
export default ComponentA;

Child prop value not updated on Window , but i can see it get updated in console

I dont know what i am doing wrong in this code, the prop value 'number' is not updating on front end , although in the console logs it value does get increament.
import React from 'react';
import { render } from 'react-dom';
class Parent extends React.Component{
constructor(props){
super(props);
this.number=0;
this.changeValue=this.changeValue.bind(this);
}
changeValue(){
console.log('-------------this.number',this.number);
this.number=this.number+1;
}
render(){
return(
<div>
<Child callMe={this.changeValue} increaseNo={this.number}></Child>
</div>
)
}
}
class Child extends React.Component{
render(){
return(
<div>
<button onClick={this.props.callMe}>CLick Me</button>
<h1>{this.props.increaseNo}</h1>
</div>
)
}
}
render(<Parent/> , document.getElementById('root'));
You have to store this.number inside the component state, the component will only be re-rendered if its state changes or it receives new props.
class Parent extends React.Component{
constructor(props){
super(props);
this.state = {
number: 0
}
this.changeValue=this.changeValue.bind(this);
}
changeValue(){
this.setState({number: this.state.number + 1});
}
render(){
return(
<div>
<Child callMe={this.changeValue} increaseNo={this.state.number}></Child>
</div>
)
}
}
class Child extends React.Component{
render(){
return(
<div>
<button onClick={this.props.callMe}>CLick Me</button>
<h1>{this.props.increaseNo}</h1>
</div>
)
}
}
jsfiddle

Resources