如何基于多个条件反应钩子进行过滤

时间:2020-09-28 00:32:05

标签: javascript reactjs react-hooks

目前,我可以一一过滤,但是,我不确定如何一次过滤多个条件。例如

我可以过滤option.option_activity_type === 'SWEEP'很好,但是如果我想像option.sentiment === 'BULLISH'一样添加到过滤器中,它将重置过滤器并为我提供所有符合此条件的选项(option.sentiment === 'BULLISH' ),而不是给我同时选择options_activity_type === 'SWEEP'option.sentiment === 'BULLISH'的选项。

我正在寻找一种将多个过滤器添加到我的应用程序的方法。我的代码在下面。

{
        "ticker": "QQQ",
        "put_call": "CALL",
        "time": "13:49:38",
        "sentiment": "BULLISH",
        "option_symbol": "QQQ200717C00233000",
        "option_activity_type": "SWEEP",
        "open_interest": "4555",
        "date_expiration": "2020-07-17",
        "date": "2020-06-08",
        "description": "Invesco QQQ Trust, Series 1 Option Alert: Jul 17 $233 Calls Sweep (15) near the Ask: 1000 @ $10.621 vs 4555 OI; Ref=$238.725",
        "ask": "10.66",
        "cost_basis": "1062100.0",
        "trade_count": "15",
        "strike_price": "233.00",
        "updated": "1591624358",
        "volume": "1001",
        "option_id": "5ede42a6af1f880001bb4118"
      },
      {
        "ticker": "QQQ",
        "put_call": "CALL",
        "time": "13:49:39",
        "sentiment": "BEARISH",
        "option_symbol": "QQQ200619C00238000",
        "option_activity_type": "SWEEP",
        "open_interest": "13844",
        "date_expiration": "2020-06-19",
        "date": "2020-06-08",
        "description": "Invesco QQQ Trust, Series 1 Option Alert: Jun 19 $238 Calls Sweep (21) near the Bid: 313 @ $4.371 vs 13844 OI; Ref=$238.725",
        "ask": "4.41",
        "cost_basis": "136812.30000000002",
        "trade_count": "21",
        "strike_price": "238.00",
        "updated": "1591624359",
        "volume": "2588",
        "option_id": "5ede42a7af1f880001bb411b"
      },
      {
        "ticker": "QQQ",
        "put_call": "PUT",
        "time": "13:52:09",
        "sentiment": "BULLISH",
        "option_symbol": "QQQ200612P00238000",
        "option_activity_type": "TRADE",
        "open_interest": "2514",
        "date_expiration": "2020-06-12",
        "date": "2020-06-08",
        "description": "Invesco QQQ Trust, Series 1 Option Alert: Fri $238 Puts at the Bid: 498 @ $2.3 vs 2514 OI; Ref=$238.85",
        "ask": "2.3",
        "cost_basis": "114539.99999999999",
        "trade_count": "1",
        "strike_price": "238.00",
        "updated": "1591624501",
        "volume": "2945",
        "option_id": "5ede4335af1f880001bb419d"
      },
import React, {useState, useEffect, useContext, useCallback} from 'react'
import {isMobile} from 'react-device-detect'
import cx from 'classnames'
import {useQuery} from '@apollo/react-hooks'
import uniqBy from 'lodash/uniqBy'
import io from 'socket.io-client'

import styles from './Flow.module.scss'
import filterStyles from './FilterSection.module.scss'

import {
  FLOW_ROW_NAME,
  ASK,
  ONE_MILL,
  FIVE_HUNDRED,
  ABOVE_ASK,
  STOCK_ONLY,
  ETFS_ONLY,
  CALLS_ONLY,
  PUTS_ONLY,
  FIFTY_CENTS,
  SWEEPS_ONLY,
  FILTER_SELECTION,
} from './flow-data'

import {
  getBidOrAskOrder,
  getNewContractPrice,
} from './FlowListFunction'

import {GET_USER_INFO, GETS_OPTIONS_BY_DATE} from '../../util/gql'

import {FirebaseContext} from '../../context/auth'
import {ENVIRONMENT} from '../../env'

import FlowList from './FlowList'
import InputField from './InputField'

export default function Flow() {
  const [options, setOptions] = useState([])
  const [filteredOptions, setFilteredOptions] = useState(false)
  const [showFilter, setShowFilter] = useState(false)
  const [searchTicker, setSearchTicker] = useState(false)
  const [searchInput, setSearchInput] = useState('')
  const [openOrders, setOpenOrders] = useState(false)
  const [oneMill, setOneMill] = useState(false)
  const [aboveAsk, setAboveAsk] = useState(false)
  const [stockOnly, setStockOnly] = useState(false)
  const [etfOnly, setEtfOnly] = useState(false)
  const [callsOnly, setCallsOnly] = useState(false)
  const [putsOnly, setPutsOnly] = useState(false)
  const [sweepsOnly, setSweepsOnly] = useState(false)
  const [fiftyCents, setFiftyCents] = useState(false)
  const [fiveHundred, setFiveHundred] = useState(false)
  const [filterSelection, setFilterSelection] = useState(FILTER_SELECTION)
  const {firebase, currentUser} = useContext(FirebaseContext)
  const socket = io(ENVIRONMENT.DATA_SERVER_URL, {transports: ['websocket']})
  const user = currentUser
  let todayOptionsTraded = []
  let today = new Date()
  let dd = String(today.getDate()).padStart(2, '0')
  let mm = String(today.getMonth() + 1).padStart(2, '0')
  let yyyy = today.getFullYear()

  today = yyyy + '-' + mm + '-' + dd
  const {loading, error, data} = useQuery(GETS_OPTIONS_BY_DATE, {
    variables: {
      inputDate: today,
      // inputTicker: searchInput,
    },
  })

  function filterData(ticker) {
    if (!ticker || ticker.length === 0) {
      clearFilter()
      return
    }

    setSearchInput(ticker)
  }

  const memoizedfilterData = useCallback(() => {
    filterData(searchInput)
  }, [searchInput])

  const reset = useCallback(() => {
    setFilterSelection(FILTER_SELECTION)
    setOpenOrders(false)
    setOneMill(false)
    setFiveMill(false)
    setAboveAsk(false)
  }, [])

  const ButtonProps = [
    {
      children: 'Clear All',
      onClick: reset,
      className: filterStyles.clear_button,
    },
    {children: 'Done', onClick: 'onClick', className: filterStyles.done_button},
  ]

  if (data !== undefined) {
    todayOptionsTraded = data.getOptionsByDate
  }

  function filterInput(ticker) {
    if (!ticker || ticker.length === 0) {
      setSearchTicker(false)
      filteredOptions(false)
    }

    setSearchInput(ticker)
    setSearchTicker(true)
  }

  function onFilterChange(e) {
    const {id, checked} = e.target
    if (id === ASK) {
      setOpenOrders(!openOrders)
    } else if (id === ONE_MILL) {
      setOneMill(!oneMill)
    } else if (id === ABOVE_ASK) {
      setAboveAsk(!aboveAsk)
    } else if (id === STOCK_ONLY) {
      setStockOnly(!stockOnly)
    } else if (id === ETFS_ONLY) {
      setEtfOnly(!etfOnly)
    } else if (id === CALLS_ONLY) {
      setCallsOnly(!callsOnly)
    } else if (id === PUTS_ONLY) {
      setPutsOnly(!putsOnly)
    } else if (id === SWEEPS_ONLY) {
      setSweepsOnly(!sweepsOnly)
    } else if (id === FIFTY_CENTS) {
      setFiftyCents(!fiftyCents)
    } else if (id === FIVE_HUNDRED) {
      setFiveHundred(!fiveHundred)
    }
  }

  const optionFilterFunction = option => {
    if (searchInput) {
      filteredOptions(true)
      return option.ticker === searchInput
    }

    if (openOrders) {
      return getBidOrAskOrder(option.description) === ('A' || 'AA')
    }

    if (oneMill) {
      return option.cost_basis >= 1000000
    }

    if (fiveHundred) {
      return option.cost_basis >= 500000
    }

    if (stockOnly) {
      return option.underlying_type === 'STOCK'
    }

    if (etfOnly) {
      return option.underlying_type === 'ETF'
    }

    if (callsOnly) {
      return option.put_call === 'CALL'
    }

    if (putsOnly) {
      return option.put_call === 'PUT'
    }

    if (sweepsOnly) {
      return option.option_activity_type === 'SWEEP'
    }

    if (fiftyCents) {
      return getNewContractPrice(option.description).split('$')[1].trim() <= 0.5
    }

    return option
  }

  const clearFilter = useCallback(() => {
    setFilteredOptions(false)
    setSearchInput('')
    setSearchTicker(false)
  }, [])

  useEffect(() => {
    socket.on('all_options', function (data) {
      setOptions(options => [...options, ...data])
    })

    socket.on('clear', function () {
      setOptions([])
    })

    return () => {
      socket.close()
    }
  }, [])

  useEffect(() => {
    socket.on('options', data => {
      setOptions(options => uniqBy([...data, ...options], 'id'))
    })

    return () => {
      socket.close()
    }
  }, [data])

  return (
    <div className={styles.flow_background_color}>
      {!isMobile && (
        <div className={styles.desktop_view}>
          <InputField
            onChange={e => filterInput(e.target.value)}
            onKeyPress={e =>
              e.key === 'Enter' ? optionFilterFunction() : null
            }
            onClick={memoizedfilterData}
            value={searchInput}
            filterButtonClick={() => setShowFilter(!showFilter)}
            searchTicker={searchTicker}
            clearFilter={clearFilter}
            searchInput={searchInput}
          />
          {showFilter && (
            <div className={filterStyles.filter_container}>
              <div className={filterStyles.button_container}>
                {ButtonProps.map(data => {
                  return (
                    <button
                      key={data.children}
                      onClick={data.onClick}
                      className={data.className}
                    >
                      {data.children}
                    </button>
                  )
                })}
              </div>
              <div className={filterStyles.filter_selection_container}>
                {filterSelection.map(data => {
                  return (
                    <label className={filterStyles.label} key={data.name}>
                      <input
                        className={filterStyles.input_checkbox}
                        type="checkbox"
                        id={data.name}
                        onChange={onFilterChange}
                        checked={data.checked}
                      />
                      <span className={filterStyles.span_name}>
                        {data.name}
                      </span>
                    </label>
                  )
                })}
              </div>
            </div>
          )}
          <div className={styles.row_list}>
            {FLOW_ROW_NAME.map(data => {
              return (
                <div className={cx(styles.row_name)} key={data.name}>
                  {data.name}
                </div>
              )
            })}
          </div>
          <div className={styles.container_list}>
            <ul className={styles.ul_list}>
              {filteredOptions && options.length === 0 && (
                <div className={styles.no_options_found}>No Items Found</div>
              )}
              {options.filter(optionFilterFunction).map((data, index) => (
                <FlowList
                  ticker={data.ticker}
                  strike_price={data.strike_price}
                  date_expiration={data.date_expiration}
                  put_call={data.put_call}
                  option_activity_type={data.option_activity_type}
                  description={data.description}
                  sentiment={data.sentiment}
                  cost_basis={data.cost_basis}
                  updated={data.updated}
                  key={index}
                />
              ))}
            </ul>
          </div>
        </div>
      )}
    </div>
  )
}

1 个答案:

答案 0 :(得分:0)

使用您当前的方法,可以通过将过滤器填充到一组条件中来做到这一点:

  const optionFilterFunction = option => {
    const conditions = [];
    if (searchInput) {
      filteredOptions(true)
      conditions.push( option.ticker === searchInput )
    }

    if (openOrders) {
      conditions.push( getBidOrAskOrder(option.description) === ('A' || 'AA') )
    }

    if (oneMill) {
      conditions.push( option.cost_basis >= 1000000 )
    }

    if (fiveHundred) {
      conditions.push( option.cost_basis >= 500000 )
    }

    if (stockOnly) {
      conditions.push( option.underlying_type === 'STOCK' )
    }

    if (etfOnly) {
      conditions.push( option.underlying_type === 'ETF' )
    }

    if (callsOnly) {
      conditions.push( option.put_call === 'CALL' )
    }

    if (putsOnly) {
      conditions.push( option.put_call === 'PUT' )
    }

    if (sweepsOnly) {
      conditions.push( option.option_activity_type === 'SWEEP' )
    }

    if (fiftyCents) {
      conditions.push( getNewContractPrice(option.description).split('$')[1].trim() <= 0.5 )
    }

    return conditions.every(Boolean);
  }
相关问题