user12711263
user12711263

Reputation:

Pass back selected value to parent component React Hook

I have a Translator component which has a LanguageSelector component which is basically just a dropdown menu with predefined values. I want to update my state of selectedLanguage in Translator based on my selected value from the dropdown in LanguageSelector. I tried to pass a callback function from the Translator but it doesn't seem to work. Can you look at my code and point me to a direction to start?

Here is my code: Translator:

const Translator = () => {
  const [selectedLanguage, setSelectedLanguage] = useState(null);

  const updateLanguage = (language) => {
    console.log(language);
    setSelectedLanguage(language);
  };

  return (
    <LanguageSelector
      onLanguageUpdate={updateLanguage}
    />
  );
};

export default Translator;

and here is my LanguageSeletor:

import "bootstrap/dist/css/bootstrap.min.css";
import React, {
  useState,
  useContext,
  useEffect,
  useCallback,
  useMemo,
} from "react";
import DropdownButton from "react-bootstrap/DropdownButton";
import Dropdown from "react-bootstrap/Dropdown";

const LanguageSelector = ({ props }) => {
  const [selectedLanguage, setSelectedLanguage] = useState(null);
  const handleSelect = (language) => {
    setSelectedLanguage(language);
    props.onLanguageUpdate(language);
  };
  return (
    <DropdownButton
      alignRight
      title="Select language"
      id="dropdown-menu-align-right"
      onSelect={() => handleSelect(selectedLanguage)}
    >
      <Dropdown.Item eventKey="yoda">Yoda</Dropdown.Item>
      <Dropdown.Item eventKey="dothraki">Dothraki</Dropdown.Item>
      <Dropdown.Item eventKey="shakespeare">Shakespeare</Dropdown.Item>
      <Dropdown.Item eventKey="sith">Sith</Dropdown.Item>
      <Dropdown.Item eventKey="lolcat">LOLCat</Dropdown.Item>
      <Dropdown.Item eventKey="klingon">Klingon</Dropdown.Item>
      <Dropdown.Item eventKey="minion">Minion</Dropdown.Item>
      <Dropdown.Item eventKey="valyrian">Valyrian</Dropdown.Item>
      <Dropdown.Item eventKey="pirate">Pirate</Dropdown.Item>
      <Dropdown.Item eventKey="hacker">Hacker</Dropdown.Item>
    </DropdownButton>
  );
};

export default LanguageSelector;

Thank you!

Upvotes: 1

Views: 832

Answers (1)

Shubham Verma
Shubham Verma

Reputation: 5054

There are couple of issues here: 1.

const LanguageSelector = ({ props }) => {

You are passing props and not destructring correctly.

Either do this:

const LanguageSelector = ( props ) => {


or do this:

const LanguageSelector = ({ onLanguageUpdate }) => {
//directly call onLanguageUpdate
}

After that you are not using onSelect correctly:

onSelect={() => handleSelect(selectedLanguage)}

as you can see you are passing selectLanguage which is always be null. You need to pass value as parameter. This i found from there docs. So it should be like this:

onSelect={(eventKey, event) => handleSelect(eventKey)}

Then all code good to go. For reference here is full code:

import React, {
  useState,
  useContext,
  useEffect,
  useCallback,
  useMemo
} from "react";
import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";

import DropdownButton from "react-bootstrap/DropdownButton";
import Dropdown from "react-bootstrap/Dropdown";

const LanguageSelector = (props) => {
  const [selectedLanguage, setSelectedLanguage] = useState(null);
  const handleSelect = (language) => {
    console.log("I am calling from LanguageSelector", language);
    setSelectedLanguage(language);
    props.onLanguageUpdate(language);
  };
  return (
    <DropdownButton
      alignRight
      title="Select language"
      id="dropdown-menu-align-right"
      onSelect={(eventKey, event) => handleSelect(eventKey)}
    >
      <Dropdown.Item eventKey="yoda">Yoda</Dropdown.Item>
      <Dropdown.Item eventKey="dothraki">Dothraki</Dropdown.Item>
      <Dropdown.Item eventKey="shakespeare">Shakespeare</Dropdown.Item>
      <Dropdown.Item eventKey="sith">Sith</Dropdown.Item>
      <Dropdown.Item eventKey="lolcat">LOLCat</Dropdown.Item>
      <Dropdown.Item eventKey="klingon">Klingon</Dropdown.Item>
      <Dropdown.Item eventKey="minion">Minion</Dropdown.Item>
      <Dropdown.Item eventKey="valyrian">Valyrian</Dropdown.Item>
      <Dropdown.Item eventKey="pirate">Pirate</Dropdown.Item>
      <Dropdown.Item eventKey="hacker">Hacker</Dropdown.Item>
    </DropdownButton>
  );
};

const Translator = () => {
  const [selectedLanguage, setSelectedLanguage] = useState(null);

  const updateLanguage = (language) => {
    console.log("I am calling from Translator", language);
    setSelectedLanguage(language);
  };

  return <LanguageSelector onLanguageUpdate={updateLanguage} />;
};

export default function App() {
  return (
    <div className="App">
      <Translator />
    </div>
  );
}


Here is the demo: https://codesandbox.io/s/nervous-mcclintock-l356e?file=/src/App.js:0-1821

Upvotes: 1

Related Questions