ashfaqrafi
ashfaqrafi

Reputation: 500

Send searchParam data from one Component to another component in reactjs

I have one Component which shows a list of data in a dropdown and there is an option to search these data which works as a filter. Here is my code:

import React, { useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import Popover from '../../Popover';
import Input from '../../Input';
import Icon from '../../Icon';
import IconButton from '../../IconButton';

const DropDownFilter = props => {
  const { label, options, onChange, isSearchEnabled } = props;
  const [activeOption, setActiveOption] = useState({});
  const [filter, setfilter] = useState('');

  const searchFilter = event => {
    setfilter(event.target.value);
  };

  const removeFilter = () => {
    setfilter('');
  };

  const lowercasedFilter = filter.toLowerCase();
  const filteredData = options.filter(item => {
    return Object.keys(item).some(
      key => typeof item[key] === 'string' && item[key].toLowerCase().includes(lowercasedFilter)
    );
  });

  const labelText = activeOption.label ? activeOption.label : label;

  const handleSelectedOption = option => {
    setActiveOption(option);
    onChange(option);
  };

  return (
    <div className="filter">
      <Popover linkText={labelText} size="small" direction="bottom-left">
        {isSearchEnabled && (
          <div className="filter__search">
            <Input
              value={filter}
              onChange={searchFilter}
              preIcon={
                <div role="presentation">
                  <Icon name="search" />
                </div>
              }
              placeholder="Search"
              postIcon={
                filter.length > 0 && (
                  <IconButton
                    icon={<Icon name="close" />}
                    size="tiny"
                    onClick={removeFilter}
                    standalone={true}
                    isIconOnly={true}
                  />
                )
              }
            />
          </div>
        )}
        <ul className="filter__options filter__options--scrollbar">
          {filteredData.map(option => (
            <li
              key={option.value}
              role="presentation"
              className={classNames('filter__options-option', {
                'filter__options-option--active': option.value === activeOption.value,
              })}
              onClick={() => handleSelectedOption(option)}
            >
              {option.label}
            </li>
          ))}
        </ul>
      </Popover>
    </div>
  );
};

DropDownFilter.defaultProps = {
  label: 'Filter Menu',
  options: [],
  isSearchEnabled: true,
};

DropDownFilter.propTypes = {
  label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
  options: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
      value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    })
  ),
  onChange: PropTypes.func.isRequired,
  isSearchEnabled: PropTypes.bool,
};

export default DropDownFilter;

Here is a gif of it: https://recordit.co/HtalUtuPsj

Now during searching I want to send the value of the search param to another component, the value will be used to search from a DB or any other external data source which is being handled in that new component. Such as, if I am searching for Ratings, this component should search for it in the existing options list it has in its own component, as well as the same time it will search for Ratings in any other external data source or DB. This external network call, search or any other functionality will be processed in the other component. So this component will only send the search param; for example Ratings to the other component in real time.

I can think of an idea like I will get the searchParam in a state and pass the setState value to a new props which will be called through an onSearchParamChange function, this new function will pass the data through a callback and the other component will get the data through calling that props of this component. I am not sure if this is the correct way and also I am not able to implement this thought in the code either. Is there any better way to do it? if so what would be that coding implementation?

Upvotes: 0

Views: 290

Answers (1)

jamomani
jamomani

Reputation: 983

If you need to pass to a parent component you should be able to use for example the onChange prop which is passed to your component, like you are doing in the handleSelectedOption function. That function is in fact passing the chosen option to the parent component. If you want to pass to the parent component when the user is typing, then you should call the onChange function also in searchFilter:

  const searchFilter = event => {
    const option = event.target.value);
    setfilter(option);
    onChange(option);
  };

If you want to pass it to a child component, the you can just pass it as prop:

<ChildComponent filter={ filter } />

Upvotes: 1

Related Questions