我正在尝试在所选日期之前根据另一个 select 过滤反应中的 select 组件

i`m trying to filter a select component in react based on an other select by the date chosen

我希望根据用户 select 的年份显示球员。例如,如果我在第一个 select 选择 2011,在第二个 select 只显示 2011 年出生的球员。我为每年创建一个 if 语句并检查他是否出生在 1 月 1 日之间那一年和 12 月 31 日,但我认为这样做效率不高(100 个 if 语句)。我正在使用 React js

代码如下

import React, { useState, useEffect } from 'react';
import './style.css';

export default function App() {
  const vitet = [
    2030, 2029, 2028, 2027, 2026, 2025, 2024, 2023, 2022, 2021, 2020, 2019,
    2018, 2017, 2016, 2015, 2014, 2013, 2012, 2011, 2010, 2009, 2008, 2007,
    2006, 2005, 2004, 2003, 2002, 2001, 2000, 1999, 1998, 1997, 1996, 1995,
    1994, 1993, 1992, 1991, 1990, 1989, 1988, 1987, 1986, 1985, 1984, 1983,
    1982, 1981, 1980, 1979, 1978, 1977, 1976, 1975, 1974, 1973, 1972, 1971,
    1970, 1969, 1968, 1967, 1966, 1965, 1964, 1963, 1962, 1961, 1960, 1959,
    1958, 1957, 1956, 1955, 1954, 1953, 1952, 1951, 1950, 1949, 1948, 1947,
    1946, 1945, 1944, 1943, 1942, 1941, 1940, 1939, 1938, 1937, 1936, 1935,
    1934, 1933, 1932, 1931, 1930, 1929, 1928, 1927, 1926, 1925, 1924, 1923,
    1922, 1921, 1920, 1919, 1918, 1917, 1916, 1915, 1914, 1913, 1912, 1911,
  ];

  const [year, setyear] = useState('');
  const [option, setOption] = useState([]);
  const [players, setPlayers] = useState([
    { playerName: 'ANn', playerId: '1', birthday: '2010-01-02' },
    { playerName: 'Eli', playerId: '2', birthday: '2011-01-02' },
    { playerName: 'Benn', playerId: '3', birthday: '2012-01-02' },
    { playerName: 'Klo', playerId: '4', birthday: '2013-01-02' },
    { playerName: 'Jhon', playerId: '5', birthday: '2014-01-02' },
    { playerName: 'Billy', playerId: '6', birthday: '2015-01-02' },
    { playerName: 'Dani', playerId: '7', birthday: '2015-01-02' },
    { playerName: 'Molly', playerId: '8', birthday: '2016-01-02' },
    { playerName: 'emily', playerId: '9', birthday: '2000-01-02' },
  ]);
  let secondOptions = players;

  if (year === '2010') {
    secondOptions = players.filter(
      (players) =>
        players.birthday >= '2010-01-01' && players.birthday <= '2010-12-31'
    );
  } else if (year === '2011') {
    secondOptions = players.filter(
      (players) =>
        players.birthday >= '2011-01-01' && players.birthday <= '2011-12-31'
    );
  } else if (year === '2012') {
    secondOptions = players.filter(
      (players) =>
        players.birthday >= '2012-01-01' && players.birthday <= '2012-12-31'
    );
  } else if (year === '2013') {
    secondOptions = players.filter(
      (players) =>
        players.birthday >= '2013-01-01' && players.birthday <= '2013-12-31'
    );
  } else if (year === '2014') {
    secondOptions = players.filter(
      (players) =>
        players.birthday >= '2014-01-01' && players.birthday <= '2014-12-31'
    );
  } else if (year === '2015') {
    secondOptions = players.filter(
      (players) =>
        players.birthday >= '2015-01-01' && players.birthday <= '2015-12-31'
    );
  } else if (year === '2016') {
    secondOptions = players.filter(
      (players) =>
        players.birthday >= '2016-01-01' && players.birthday <= '2016-12-31'
    );
  } else if (year === '2017') {
    secondOptions = players.filter(
      (players) =>
        players.birthday >= '2017-01-01' && players.birthday <= '2017-12-31'
    );
  } else if (year === '2018') {
    secondOptions = players.filter(
      (players) =>
        players.birthday >= '2018-01-01' && players.birthday <= '2018-12-31'
    );
  } else if (year === '2019') {
    secondOptions = players.filter(
      (players) =>
        players.birthday >= '2019-01-01' && players.birthday <= '2019-12-31'
    );
  } else if (year === '2000') {
    secondOptions = players.filter(
      (players) =>
        players.birthday >= '2000-01-01' && players.birthday <= '2000-12-31'
    );
  } else {
    secondOptions = [];
  }

  useEffect(() => {
    // Update the document title using the browser API
    console.log('playerat per ke optioni', secondOptions);
  });
  return (
    <div>
      <h1>Hello StackBlitz!</h1>
      <p>Start editing to see some magic happen :)</p>
      <select name="" id="" onChange={(e) => setyear(e.target.value)}>
        {/* <option value="2010">2010</option>
        <option value="2011">2011</option>
        <option value="2012">2012</option>
        <option value="2013">2013</option>
        <option value="2014">2014</option>
        <option value="2015">2015</option>
        <option value="2016">2016</option>
        <option value="2017">2017</option>
        <option value="2018">2018</option>
        <option value="2019">2019</option> */}
        {vitet.map((item) => (
          <option value={item}>{item}</option>
        ))}
      </select>
      <select>
        {secondOptions.map((item) => (
          <option key={item.playerId}>{item.playerName}</option>
        ))}
      </select>
      <p> {year}</p>
    </div>
  );
}

查看此处的代码编辑器。

https://stackblitz.com/edit/react-jruwh9

好吧,如果你真的想把日期当作字符串(查看答案末尾的注释),你可以做的是下面的

import React, { useState } from 'react';
import './style.css';

const years = [
  2030, 2029, 2028, 2027, 2026, 2025, 2024, 2023, 2022, 2021, 2020, 2019,
  2018, 2017, 2016, 2015, 2014, 2013, 2012, 2011, 2010, 2009, 2008, 2007,
  2006, 2005, 2004, 2003, 2002, 2001, 2000, 1999, 1998, 1997, 1996, 1995,
  1994, 1993, 1992, 1991, 1990, 1989, 1988, 1987, 1986, 1985, 1984, 1983,
  1982, 1981, 1980, 1979, 1978, 1977, 1976, 1975, 1974, 1973, 1972, 1971,
  1970, 1969, 1968, 1967, 1966, 1965, 1964, 1963, 1962, 1961, 1960, 1959,
  1958, 1957, 1956, 1955, 1954, 1953, 1952, 1951, 1950, 1949, 1948, 1947,
  1946, 1945, 1944, 1943, 1942, 1941, 1940, 1939, 1938, 1937, 1936, 1935,
  1934, 1933, 1932, 1931, 1930, 1929, 1928, 1927, 1926, 1925, 1924, 1923,
  1922, 1921, 1920, 1919, 1918, 1917, 1916, 1915, 1914, 1913, 1912, 1911,
];

const players = [
  { playerName: 'ANn', playerId: '1', birthday: '2010-01-02' },
  { playerName: 'Eli', playerId: '2', birthday: '2011-01-02' },
  { playerName: 'Benn', playerId: '3', birthday: '2012-01-02' },
  { playerName: 'Klo', playerId: '4', birthday: '2013-01-02' },
  { playerName: 'Jhon', playerId: '5', birthday: '2014-01-02' },
  { playerName: 'Billy', playerId: '6', birthday: '2015-01-02' },
  { playerName: 'Dani', playerId: '7', birthday: '2015-01-02' },
  { playerName: 'Molly', playerId: '8', birthday: '2016-01-02' },
  { playerName: 'emily', playerId: '9', birthday: '2000-01-02' },
];

export default function App() {
  const [year, setYear] = useState('');

  // With strings, as your code
  const secondOptions = players.filter(player => player.birthday.startsWith(`${year}-`));

  // Or, with Date (in this case it would be better to perform the conversion in the original object, instead of here, for better performance)
  // const secondOptions = players.filter(player => new Date(player.birthday).getFullYear() === year);

  return (
    <div>
      <h1>Hello StackBlitz!</h1>
      <p>Start editing to see some magic happen :)</p>
      <select onChange={(e) => setYear(e.target.value)}>
        {years.map((item) => (
          <option key={`year_option_${item}`} value={item}>{item}</option>
        ))}
      </select>
      <select>
        {secondOptions.map((item) => (
          <option key={`second_option_${item.playerId}`} value={item.playerId}>{item.playerName}</option>
        ))}
      </select>
      <p>{year}</p>
    </div>
  );
}

我从组件中移出了一些变量,因为它们现在不需要在组件中了。另外,我添加了一些缺失的键并删除了未使用的变量,以供演示。

关于日期的重要说明

通常将日期视为 Date 而不是字符串。

如果您决定处理日期广告 Date 实例,那么您可以使用 JavaScript 中提供的功能,并执行与我在发布的代码中显示的类似的操作,在过滤器部分。

正如@GiorgiMoniava 在此处的评论中提到的,如果您选择 Date 解决方案

,则在将字符串转换为 Date 时请注意此类问题

我将从优化您的年份选择开始。使用开始年份,并填充一个数组直到现在。没有人会在未来出生……但是 ;)

接下来只过滤那些有球员的年份,接下来如果你设置年份,只需过滤当年的球员。

import React, { useState } from 'react';
import './style.css';

export default function App() {
  const START_YEAR = 1911;
  const END_YEAR = new Date().getFullYear() + 1;

  const [year, setyear] = useState('');
  const [players, setPlayers] = useState([
    { playerName: 'ANn', playerId: '1', birthday: '2010-01-02' },
    { playerName: 'Eli', playerId: '2', birthday: '2011-01-02' },
    { playerName: 'Benn', playerId: '3', birthday: '2012-01-02' },
    { playerName: 'Klo', playerId: '4', birthday: '2013-01-02' },
    { playerName: 'Jhon', playerId: '5', birthday: '2014-01-02' },
    { playerName: 'Billy', playerId: '6', birthday: '2015-01-02' },
    { playerName: 'Dani', playerId: '7', birthday: '2015-01-02' },
    { playerName: 'Molly', playerId: '8', birthday: '2016-01-02' },
    { playerName: 'emily', playerId: '9', birthday: '2000-01-02' },
  ]);

  const vitet = new Array(END_YEAR - START_YEAR)
    .fill(START_YEAR)
    .map((current, i) => current + i)
    .filter(
      (year) =>
        players.find(
          (player) => player.birthday.substr(0, 4) === year.toString()
        ) !== undefined
    );

  return (
    <div>
      <h1>Hello StackBlitz!</h1>
      <p>Start editing to see some magic happen :)</p>
      <select name="" id="" onChange={(e) => setyear(e.target.value)}>
        {vitet.map((item) => (
          <option value={item}>{item}</option>
        ))}
      </select>
      <select>
        {players
          .filter((player) => player.birthday.substr(0, 4) === year.toString())
          .map((item) => (
            <option key={item.playerId}>{item.playerName}</option>
          ))}
      </select>
      <p> {year}</p>
    </div>
  );
}