Johnny88520
Johnny88520

Reputation: 157

How to communicate between two components in Reactjs

I'm a newbie in React. Why can't my data pass to another component?? My idea is after the user select option tag, then it will load some audio files based off the selection. But it's not working. What did I miss?

Or is there a better to do it?

This is my dropdown component

import React from 'react';
import Playlist from './Playlist/Playlist.js';

class Dropdown extends React.Component {
  constructor (props) {
    super(props);
    this.state = {value: "1"};

    this.handleChange = this.handleChange.bind(this);
    this.handleEnter = this.handleEnter.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});

    console.log("Hello");
    console.log(event.target.value);
    console.log(typeof(event.target.value));
  }

  handleEnter(event) {

    alert("Clicked: " + this.state.value);
    event.preventDefault();
  }

  render (){
    return (
      <form onSubmit={this.handleEnter} >
        <label>
        <div className="langueageSelection">
          <Playlist langueageSelection={this.handleChange.bind(this)} />

          <select value={this.state.value} onChange={this.handleChange} >

            <option value=""> Please select a language </option>
            <option value="1"> English (American) </option>
            <option value="2"> Chinese (Mandarin) </option>
          </select>

      </div>
    </label>
    <input type="submit" value="Enter" className="EnterButton"/>
  </form>
);
}
}

export default Dropdown;

This is my playlist component.

import React from 'react';
class Playlist extends React.Component {

  handleChange({target}){
    this.props.langueageSelection(target.value)
  }

  render() {
    if (this.props.langueageSelection === "1"){
      console.log("English");

    }
    else if(this.props.langueageSelection === "2"){
      console.log("Chinese");
    }
    return (
      <div> Hi</div>
     );
 }
}

export default Playlist;

This is my entry component:

import React from 'react';
import mind_zebra from '../../images/MindScribe-zebra.png';
import Dropdown from '../Dropdown/Dropdown.js';


class Entry extends React.Component {

  state = { hideZebraPic : false};

  onClickHandler = () => {
    this.setState( prev => ({ hideZebraPic : !prev.hideZebraPic }));
  };

  render() {
    if (this.state.hideZebraPic) {
      return (
        <div>
          <Dropdown />
        </div>
      );
    } else {
      return (
        <div>
          <img src={mind_zebra} onClick={this.onClickHandler} className="MindZebraPic" alt="zebra"/>
        </div>
      );
    }
  }
}

Here's my structure of directory:

src
  |
  audio
    - English audios
    - Chinese audios
  components
     |
     Dropdown
        |
        playlist
          - playlist.js
        dropdown.js
     |
     Entry
         |
         entry.js
     |
     Home
         |
         App.js

Upvotes: 0

Views: 2571

Answers (2)

deathangel908
deathangel908

Reputation: 9689

Or is there a better to do it?

Please take a look Single source of truth and its implementation by Redux or MobX

enter image description here

Upvotes: 1

Piotr
Piotr

Reputation: 31

Maybe could you please specify what exactly does not work? Playlist does not receive selected language? Should it?

Because now, it looks like this:

<Playlist langueageSelection={this.handleChange.bind(this)} />

You pass function to Playlist, right? And as I understand, role of Playlist is to render some content, based on selections made in parent component, which is Dropdown? Why would you pass a function to the children component? An why would you decorate it with .bind(this)? You've bound "it" already in constructor (which is a "Dropdown" as I understand).

If you really need to get it working as it is:

In Dropdown, pass the "value" as a prop to child

<Playlist langueageSelection={this.state.value} />

In Playlist, I'm not quite sure if you need this function to be passed.

import React from 'react';
class Playlist extends React.Component {


  render() {
    if (this.props.langueageSelection === "1"){
      console.log("English");

    }
    else if(this.props.langueageSelection === "2"){
      console.log("Chinese");
    }
    return (
      <div> Hi</div>
     );
 }
}

export default Playlist;

For further development:

I think you could get in touch with some programming patterns of React. Please make some research on "stateless components updating parent's state". I don't know your idea about whole application, but I feel that Playlist should not be a child of a Dropdown. I would propose something like this:

Dropdown and Playlist are siblings. Let's say that they parent App. App is stateful component. Dropdown and Playlist are stateless components. App passes function ChangeLanguage to the Dropdown. ChangeLanguage is bound to App. Function ChangeLanguage handles selection of lang in Dropdown, takes event and updates App state with event.target.value. Then App passes its state to Playlist as a prop.

I hope that I understood your issue right.

Upvotes: 0

Related Questions