downshift-js/downshift

Add onSelect prop to hooks

Open

#1139 opened on Aug 4, 2020

View on GitHub
 (11 comments) (0 reactions) (0 assignees)JavaScript (11,761 stars) (980 forks)batch import
enhancementhelp wanted

Description

TLDR:

Ok, I understand. You need onSelect. Let's develop it, we will use this issue to track it.

You probably need to work in hooks/utils.js on callOnChangeProps. Call onChange if there if newState has selectedItem and we have onChange prop.

Also add unit tests, Typescript and documentation. See Downshift README for the last part. Good luck!

P.S. maybe you can also take #1042 to finish it if you feel like adding features? It should only need documentation and tests.

-----Initial Issue ----

  • downshift version: 6.0.2
  • node version: 12.18.3
  • npm (or yarn) version: 6.14.6

Relevant code or config

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

export default function App() {
  const options = [
    { id: 1, value: "Steak" },
    { id: 2, value: "Pasta" },
    { id: 3, value: "Rice" },
    { id: 4, value: "Cookie" }
  ];

  const [selectedOption, setSelectedOption] = useState(null);

  const onChangeAutocompleteInputField = selection => {
    console.log(selection);
    setSelectedOption(selection);
  };

  return (
    <div className="App">
      <Downshift
        onSelect={selection => {
          onChangeAutocompleteInputField(selection);
        }}
        itemToString={item => (item ? item.value : "")}
      >
        {({
          getInputProps,
          getMenuProps,
          getItemProps,
          isOpen,
          inputValue,
          reset
        }) => (
          <div>
            <input
              {...getInputProps({
                placeholder: "Eat something",
                onChange: reset
              })}
            />
            <div {...getMenuProps()}>
              {isOpen && (
                <div className="downshift-wrap">
                  {options
                    .filter(
                      item =>
                        !inputValue ||
                        item.value
                          .toLowerCase()
                          .includes(inputValue.toLowerCase())
                    )
                    .map((item, index) => (
                      <div
                        className="downshift-item"
                        {...getItemProps({ key: item.id, index, item })}
                        key={item.id}
                      >
                        {item.value}
                      </div>
                    ))}
                </div>
              )}
            </div>
          </div>
        )}
      </Downshift>
      {<p>You ate: {selectedOption ? selectedOption.value : null}</p>}
    </div>
  );
}

What you did: I try to make the input field value turns blank after selecting an option from the list. I read the documentation and searched for previous issues in this repo and found that some examples in https://github.com/downshift-js/downshift/issues/177#issuecomment-327575402, so I call reset in input onChange prop with an intention to reset the input state back to the starting point (which is the inputValue is blank and the selectedItem is null).

What happened: The inputValue doesn't reset back to blank. Now I'm not sure what do I miss.

Reproduction repository:

CodeSandbox URL: https://codesandbox.io/s/downshift-how-to-reset-inputvalue-after-running-onselect-0ew1w

Problem description: How to reset inputValue state after running onSelect while letting Downshift handles its own state all of the time except for the custom action I defined to clear inputValue when an option is selected.

Suggested solution: More examples on how to use each prop would be helpful

Contributor guide