数组中无法识别组件 [英] Component Not Being Recognised In Array

查看:69
本文介绍了数组中无法识别组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试动态渲染元素,但是当我尝试从数组中拼接组件时,它并没有被删除.

  const [cardsInGrid,setCards] = React.useState([]);const [showReactions,setShowReactions] = React.useState(false);const onReactionsClick =()=>{setShowReactions(!showReactions);};useEffect(()=> {如果(showReactions){setCards(cardsInGrid.concat(< Reactions/>)));}否则,如果(!showReactions){console.log(cardsInGrid);var index = cardsInGrid.indexOf(< Reactions/>));console.log(index);如果(索引> -1){setCards(cardsInGrid.splice(index,1));console.log(cardsInGrid);}}},[showReactions]); 

第一个if语句中的concat有效,但是console.log(index)每次都返回-1.是我拥有的组件.

组件数组

  const componentList = [{id:标签",组件:标签},{id:反应",成分:反应},{id:"emojistats",组成部分:EmojiStats},{id:过滤器",组件:过滤器},]; 

如果我有一个预定义的数组,我将如何渲染这些组件?

解决方案

注意::如果您不仅仅需要过滤单个组件,那么通用的解决方案可以是存储存储的组件配置ID映射,以使用array :: includes

  const [filterBy,setFilterBy] = useState({});//通过名称处理添加/删除过滤器的逻辑//即filterBy = {反应:反应",...等}useEffect(()=> {const过滤器= Object.values(filterBy);如果(filters.length){//如果id匹配过滤器中的任何内容,则过滤掉组件setCardsInGrid(componentList.filter(({{id})=> filters.include(id)));} 别的 {//重置为完整的组件列表数组setCardsInGrid(componentList);}}, [过滤]); 

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?

解决方案

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]);

这篇关于数组中无法识别组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆