Dharmik Shah
Dharmik Shah

Reputation: 103

How to pass the data from child to parent? when parent is class based and child is functional based

I want to pass the data which is anything like, array, strings, numbers into the App(Parent) Component) from the Child1(Child) components.

There's a parent who is class-based and the child is functional based.

Parent:

import React, { Component } from "react";
import "./App.css";
import Child1 from "./Child1/Child1";



class App extends Component {
  state = { message: "" };

  callbackFunction = (event) => {
    this.setState({
      message: event.target.value
    });
  }

  render() {
    return (
      <div className="App">
        <Child1 />
      </div>
    );
  }
}

export default App;

Child

import React from 'react'

const Child1 = (props) => {
    return (
        <div>

        </div>
    );
}

export default Child1;

Upvotes: 1

Views: 681

Answers (3)

Ramesh Reddy
Ramesh Reddy

Reputation: 10652

If you want to send some data to the parent component upon clicking a button that's in the child component, you can do it this way:

import React from 'react'

const Child1 = React.memo((props) => {
    return (
        <div>
         <button onClick={() => {props.clicked('some data')}} type="button">Click me to send data<button>
        </div>
    );
})

export default Child1;

now you can assign a function to the clicked prop in your parent component and that gets called when the button in the child component is clicked:

class App extends Component {
  state = { message: "" };

  callbackFunction = (event) => {
    this.setState({
      message: event.target.value
    });
  }
  
  clicked = (data) => { // this func. will be executed
   console.log(data);
  }

  render() {
    return (
      <div className="App">
        <Child1 clicked={this.clicked}/>
      </div>
    );
  }
}

Upvotes: 7

Md. Abu Sayed
Md. Abu Sayed

Reputation: 2486

I have founded another solution for you using combine Functional-Class-functional component pass data. here the live code for https://codesandbox.io Click and check that.

Also same code added bellow here:

app component

import React, { useState } from "react";
import "./styles.css";

import Child from "./child";

export default function App() {
  const [name, setName] = useState("Orignal Button");
  const [count, setCount] = useState(0);

  const handleClick = _name => {
    setName(_name);
    setCount(count + 1);
  };

  const resetClick = e => {
    setName("Orignal Button");
    setCount(0);
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Child
        name={name + " - " + count}
        handleClick={handleClick}
        resetClick={resetClick}
      />
    </div>
  );
}

child1 component

import React from "react";

import Child2 from "./child2";

class Child extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <>
        <h2>This is child</h2>
        <button onClick={e => this.props.handleClick("New Name changed")}>
          {this.props.name}
        </button>
        <Child2 handleChilc2Click={this.props.resetClick} />
      </>
    );
  }
}

export default Child;

Another component Child2

import React from "react";

const Child2 = props => {
  return (
    <>
      <h2>Child 2</h2>
      <button onClick={e => props.handleChilc2Click(e)}>
        Click me for reset Parent default
      </button>
    </>
  );
};

export default Child2;

You can some help from it. Thanks

Upvotes: 0

HMR
HMR

Reputation: 39250

You can pass a function to Child (called Counter in the example) that will change Parent state. Since you pass the same reference for this function every time (this.increment) the only Children that will render are those that changed.

const Counter = React.memo(
  //use React.memo to create pure component
  function Counter({ counter, increment }) {
    console.log('rendering:', counter.id)
    // can you gues why prop={new reference} is not a problem here
    //  this won't re render if props didn't
    //  change because it's a pure component
    return (
      <div>
        <div>counter is {counter.count}</div>
        <button onClick={() => increment(counter.id)}>
          +
        </button>
      </div>
    )
  }
)

class Parent extends React.PureComponent {
  state = {
    counters: [
      { id: 1, count: 0 },
      { id: 2, count: 0 }
    ]
  }
  increment = _id =>
    this.setState({
      counters: this.state.counters.map(val =>
        _id === val.id
          ? { ...val, count: val.count + 1 }
          : val
      )
    })
  render() {
    return (
      <div>
        {this.state.counters.map(counter => (
          <Counter
            counter={counter}
            increment={this.increment}
            key={counter.id}
          />
        ))}
      </div>
    )
  }
}

//render app
ReactDOM.render(<Parent />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Upvotes: 0

Related Questions