title: React: Build Connections Among Component
body: <p>I am a beginner of React JS. Messing around to achieve VanJS event listeners.</p>
  <p>For layout, I decide to store things like <code>a panel, a button</code> as individual component.</p>
  <p>Now, I have a component <code>Movie</code> and another component <code>Button</code>, how can I <b>trigger state change of Movie by Button.onclick()?</b>.</p>
  <p>In other words, how to <b>modify a component by the event happening on another component?</b></p>
  <p>Before posting, I have read:</p>
  <ul>
  <li><a href="https://www.youtube.com/watch?v=Oioo0IdoEls" rel="nofollow noreferrer">React Basics Component Lifecycle</a></li>
  <li><a href="https://reactjs.org/docs/hooks-state.html" rel="nofollow noreferrer">Using the State Hook</a></li>
  </ul>
  <p>but tons of method followed by really confused me.</p>
  <ul>
  <li><code>useState</code></li>
  <li><code>componentWillMount</code>: immediately before initial rendering</li>
  <li><code>componentDidMount</code>: immediately after initial rendering</li>
  <li><code>componentWillReceiveProps</code>: when component receives new props</li>
  <li><code>shouldComponentUpdate</code>: before rendering, after receiving new props or state</li>
  <li><code>componentWillUpdate</code>: before rendering, after receiving new props or state.</li>
  <li><code>componentDidUpdate</code>: after component's updates are flushed to DOM</li>
  <li><code>componentWillUnmount</code>: immediately before removing component from DOM</li>
  </ul>
  <p>Following is a demo, which contains a <code>Movie</code> card and a <code>Button</code>, when the button is clicked, I want <b>the background colour of the Movie card to change</b></p>
  <p><a href="https://codesandbox.io/s/floral-rain-70ep3" rel="nofollow noreferrer">React TypeScript Code Sandbox</a></p>
  <p>the code:</p>
  <pre class="lang-js prettyprint-override"><code>import * as React from &quot;react&quot;;
  import &quot;./styles.css&quot;;
  import styled from 'styled-components';
  
  function CSSPropertiesToComponent(dict:React.CSSProperties){
    let str = '';
    for(const [key, value] of Object.entries(dict)){
        let clo = '';
        key.split('').forEach(lt=&gt;{
            if(lt.toUpperCase() === lt){
                clo += '-' + lt.toLowerCase();
            }else{
                clo += lt;
            }
        });
        str += clo + ':' + value + ';';
    }
    return str;
  }
  
  class Movie extends React.Component&lt;any, any&gt;{
    public static style:React.CSSProperties|object = {
        width: &quot;300px&quot;,
        height: &quot;120px&quot;,
        display: &quot;flex&quot;,
        justifyContent: &quot;space-around&quot;,
        alignItems: &quot;center&quot;,
        borderRadius: &quot;20px&quot;,
        filter: &quot;drop-shadow(0px 1px 3px #6d6d6d)&quot;,
        WebkitFilter: &quot;drop-shadow(3px 3px 3px #6d6d6d)&quot;,
        backgroundColor: '#'+Math.floor(Math.random()*16777215).toString(16),
        fontSize: '2.5rem',
        margin: '20px',
        color: '#fff',
    }
  
    props:React.ComponentProps&lt;any&gt;;
    state:React.ComponentState;
  
    constructor(props:any) {
        super(props);
        this.props = props;
        this.state = {style: Object.assign({}, Movie.style)}
        this.changeColor = this.changeColor.bind(this);
    }
  
    changeColor():void{
        this.setState({style: Object.assign({}, Movie.style, {backgroundColor: '#'+Math.floor(Math.random()*16777215).toString(16)})});
    }
  
    render():JSX.Element{
        let StyledMovie = styled.div`
            ${CSSPropertiesToComponent(Movie.style)}
        `;
  
        return (
            &lt;&gt;
                &lt;StyledMovie&gt;{this.props.title}&lt;/StyledMovie&gt;
            &lt;/&gt;
        )
    }
  }
  
  export default function App() {
    let MV = new Movie({title: 'the Avengers'});
      return (
          &lt;&gt;
              {MV.render()}
              &lt;button onClick={MV.changeColor}&gt;Change Color&lt;/button&gt;
          &lt;/&gt;
      )
  }
  </code></pre>
  <p>However, when clicking on the change colour button, it doesn't work and shows a warning:</p>
  <pre><code>Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the Movie component.
  </code></pre>
  <p>if anyone offers some suggestion, I will be so glad.</p>