2

how can I update a component from another in react js?

I read a lot of post but i'm not able to find my case.

I have 3 react class: Main class that contains my two react components:

`React Component A

React Component B

`

I would like to update the state of the component A using the component B.

UPDATE 1/2

I'm trying to follows the steps as you suggested but i have this problem:

i define a function in my main class:

handleArticleUpdate(codice){
alert(codice);
//this.setState({codice_articolo: codice});
}

And i'm trying to inject it in my component:

<MainGrid onArticleChanged={this.handleArticleUpdate} />

But i receive the error:

TypeError: Cannot read property 'handleArticleUpdate' of undefined

I tryed to bind the this too but the error is the same..

MY CODE:

      import React, { Component, PureComponent } from 'react';
    import { NavLink } from 'reactstrap';
    import ReactDOM from 'react-dom';

    import {Form, TabPanel} from 'devextreme-react';
    import MainGrid from './components/MainGrid';

    import VisualizzatoreArticoli from './components/VisualizzatoreArticoli';
    import './App.css';

    const headerStyle ={
      border:'1px solid'
    }

    const contentStyle ={
      border: '1px solid'
    }

    const bodyStyle ={
      backgroundColor: '#999999'

}
//import { Loading } from '../../../theme- 
 sources/bootstrap4/components/loading';
  //import { CurrencyTypeProvider } from '../../../theme- 
  sources/bootstrap4/components/currency-type-provider';

    const URL = 'http://localhost:53139/api/randomData';

    //const URL = 'https://js.devexpress.com/Demos/WidgetsGallery/data/orderItems';

    class App extends React.PureComponent {


     constructor(props) {
    super(props);
    this.state = {
      itemsHeader : [
        {
          title : 'a',

          badge: 'New'
        },
        {
          title : 'b',
          text : "1",
        },
        {
          title : 'c',
        },
      ],
      itemsContent : [
        {
          title : 'Righe',

          badge: 'New'
        },
        {
          title : 'b',
          text : "1",
        },
        {
          title : 'c',
        },
      ],
      codice_articolo :''
    }

this.handleArticleUpdate = this.handleArticleUpdate.bind(this);

  }


getInitialState(){
  return this.state.codice_articolo
}

handleArticleUpdate(codice){
  alert("");
//this.setState({codice_articolo: codice});
}



  render() {


    return (
<div style={bodyStyle}>

  <div style={headerStyle}>

        <TabPanel
          height = '300'
          items  = {this.state.itemsHeader}
          itemComponent = {function(itemData){

              switch(itemData.title){
                case "a":
                  return null
                break;
                case "b":
                return null
              break;
                case "c":
                return null
                break;


              }    
            } 
          }
          >

      </TabPanel>
  </div>
<br />
  <div  style={contentStyle}>
  <TabPanel
    height = '700'
    items  = {this.state.itemsContent}
    itemComponent = {function(itemData){

        switch(itemData.title){
          case "Righe":
            return <MainGrid onArticleChanged={this.handleArticleUpdate()} />
          break;
          case "b":
          return null
        break;
          case "c":
          return null
          break;


        }    
      } 
    }
    >

</TabPanel>
  </div>








  </div>


    );
      }
      }

     export default App;

UPDATE 2/2

I think my problem is that my component is too nested (it's inside the component TabPanel) and handleArticleUpdate is not visible in the scope.

I tryed put only

 <MainGrid onArticleChanged={this.handleArticleUpdate} />

in the render() function and all worked perfectly.

Luke
  • 517
  • 10
  • 29
  • Possible duplicate of [ReactJS Two components communicating](https://stackoverflow.com/questions/21285923/reactjs-two-components-communicating) – JJJ Aug 29 '18 at 15:21
  • Possible duplicate of [How can I get the element of another component in React.js?](https://stackoverflow.com/questions/51941434/how-can-i-get-the-element-of-another-component-in-react-js) – Bhojendra Rauniyar Aug 29 '18 at 15:32

2 Answers2

1

You need to set the methods inside the main component , and pass them down .

class mainClass extends React.Component {
  handleChangeOnA = () => {
     // ... LOGIC
  }
  render() {
      <ComponentA/>
      <ComponentB handleChangeOnA={this.handleChangeOnA}/>
  }
}

And then inside B, just call handleChangeOnA. Of course you'll also need to manage a state and pass them down as well . This process is called lifting the state up

Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
sagi
  • 40,026
  • 6
  • 59
  • 84
  • i'm not able to inject the handleChangeOnA in the component b.. i receive the error Cannot read property 'handleArticleUpdate' of undefined – Luke Aug 29 '18 at 16:39
  • Where are you trying to activate it ? Can you share the code? I suspect you’re just missing binding – sagi Aug 29 '18 at 18:40
  • i'm tying to acrivate it in my main class render functiion – Luke Aug 30 '18 at 07:01
  • @Luke you need to update the question with your code – sagi Aug 30 '18 at 07:04
  • @Luke Looks like you're not binding your functions. Either add to the constructor this line: `this.onArticleChanged = this.onArticleChanged.bind(this)` or turn it into an arrow function . – sagi Aug 30 '18 at 07:17
  • I add it on my constructor but i receive the same error. I updated the code – Luke Aug 30 '18 at 07:35
1

Lifting state up

From the React docs

Often, several components need to reflect the same changing data. We recommend lifting the shared state up to their closest common ancestor. Let’s see how this works in action.

In this case, it may be possible to move the state from component B to Main. This would be passed through the props to both components A and B, so that they both reflect the changes in state. If the state needs to be updated by component B, for example, from an onClick event, this can be done by passing a callback from Main to component B as shown already by Luke.

Keir
  • 752
  • 5
  • 8