Component Not Being Recognised In Array

流过昼夜 提交于 2020-06-28 06:05:09

问题


I am trying to dynamically render elements however when I try and splice the component from the array it does not get removed.

const [cardsInGrid, setCards] = React.useState([]);

const [showReactions, setShowReactions] = React.useState(false);

const onReactionsClick = () => {
    setShowReactions(!showReactions);
  };

useEffect(() => {
    if (showReactions) {
      setCards(cardsInGrid.concat(<Reactions />));
    } else if (!showReactions) {
      console.log(cardsInGrid);
      var index = cardsInGrid.indexOf(<Reactions />);
      console.log(index);
      if (index > -1) {
        setCards(cardsInGrid.splice(index, 1));
        console.log(cardsInGrid);
      }
    }
  }, [showReactions]);

The concat in the first if statement works but the console.log(index) returns -1 each time. is a component that I have.

EDIT: Array of components

const componentList = [
    { id: "tags", component: Tags },
    { id: "reactions", component: Reactions },
    { id: "emojistats", component: EmojiStats },
    { id: "filters", component: Filter },
  ];

How would I render these components if I have a predefined array?


回答1:


array::splice

splice mutates the array in-place, but react state works by returning new objects and array references.

array::filter

Array filter can return the new array you need. Using the second parameter of the filter function you can filter all array elements' index that isn't equal to that of the one you want to remove from the array.

The splice() method changes the contents of an array by removing or replacing existing elements and/or adding new elements in place.

useEffect(() => {
  if (showReactions) {
    setCards(cardsInGrid.concat(<Reactions />));
  } else if (!showReactions) {
    console.log(cardsInGrid);
    var index = cardsInGrid.indexOf(<Reactions />);
    console.log(index);
    if (index > -1) {
      setCards(cardsInGrid.filter((_, i) => i !== index);
      console.log(cardsInGrid);
    }
  }
}, [showReactions]);

EDIT: Using a component config array

/**
 * External source of truth
 * Could be global variable like this or passed as prop to rendering component
 */
const componentList = [
  { id: "tags", component: Tags },
  { id: "reactions", component: Reactions },
  { id: "emojiStats", component: EmojiStats },
  { id: "filters", component: Filters }
];

export default function App() {
  // cardsInGrid displays current filtered component list
  const [cardsInGrid, setCardsInGrid] = useState(componentList);
  const [showReactions, setShowReactions] = React.useState(false);

  useEffect(() => {
    if (showReactions) {
      // Filter Reactions component out
      setCardsInGrid(componentList.filter(({ id }) => id !== "reactions"));
    } else {
      // Reset to full component list array
      setCardsInGrid(componentList);
    }
  }, [showReactions]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>

      <div>
        <button type="button" onClick={() => setShowReactions(r => !r)}>
          {showReactions ? "Hide" : "Show"} Reactions
        </button>
      </div>

      {cardsInGrid.map(({ id, component: Component }) => (
        <Component key={id} />
      ))}
    </div>
  );
}

NOTE: If you need to filter by more than just a single component then a generalized solution could be a stored map of component config id's to filter by and using array::includes

const [filterBy, setFilterBy] = useState({});

// logic to handle adding/removing filters by name
// i.e. filterBy = { reactions: 'reactions', ...etc }

useEffect(() => {
  const filters = Object.values(filterBy);
  if (filters.length) {
    // Filter components out if id matches anything in filter
    setCardsInGrid(componentList.filter(({ id }) => filters.include(id)));
  } else {
    // Reset to full component list array
    setCardsInGrid(componentList);
  }
}, [filterBy]);


来源:https://stackoverflow.com/questions/61865549/component-not-being-recognised-in-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!