Показать ползунок, управляющий всем содержимым один раз при возврате элементов карты в React

#reactjs

Вопрос:

У меня есть возвращаемый контент CMS, и моя цель-установить ползунок «Год», который будет управлять контентом в зависимости от года, выбранного пользователем, щелкнув стрелку «минус/плюс».

Это мой код:

 import "./styles.css";

import React from "react";

export default function App() {
  return (
    <div className="App">
      <DatesProvider>
        {data.map((item, index) => {
          const Slice = slices[item.type];
          return <Slice section={item.section} key={index} />;
        })}
      </DatesProvider>
    </div>
  );
}

const DateContext = React.createContext({});

const DatesProvider = ({ children }) => {
  const [dates, setDates] = React.useState({});
  return (
    <DateContext.Provider value={{ dates, setDates }}>
      {children}
    </DateContext.Provider>
  );
};

const DatePicker = ({ section }) => {
  const { dates, setDates } = React.useContext(DateContext);

  React.useEffect(() => {
    // Set initial date
    setDates((prevDates) => {
      prevDates[section] = 2021;
      return { ...prevDates };
    });
    // Clean up on dismount
    return () => {
      setDates((prevDates) => {
        delete prevDates[section];
        return { ...prevDates };
      });
    };
  }, []);

  const handlePlus = () => {
    setDates((prevDates) => ({
      ...prevDates,
      [section]: prevDates[section]   1
    }));
  };

  const handleMinus = () => {
    setDates((prevDates) => ({
      ...prevDates,
      [section]: prevDates[section] - 1
    }));
  };

  return (
    <div style={{ marginTop: 30 }}>
      <button onClick={handleMinus}>-</button>
      <span>{dates[section]}</span>
      <button onClick={handlePlus}> </button>
    </div>
  );
};

const Item = ({ section }) => {
  const { dates } = React.useContext(DateContext);

  return (
    <div>
      Section: {section} | Year: {dates[section]}
    </div>
  );
};

const data = [
  { type: "DatePicker", section: "foo" },
  { type: "Item", section: "foo" },
  { type: "Item", section: "foo" },
  { type: "DatePicker", section: "bar" },
  { type: "Item", section: "bar" },
  { type: "Item", section: "bar" }
];

const slices = { DatePicker, Item };
 

В результате в настоящее время это:

введите описание изображения здесь

Как вы можете видеть, он несколько раз возвращает слайдер года, и структура похожа на эту:

 <slider> - 2021   </slider>
<section class= "container-of-all-items">
<all-items></all-items>
</section>
<slider> - 2021   </slider>
<section class= "container-of-all-items">
<all-items></all-items>
</section>
 

Моя цель состоит в том, чтобы иметь только один год обертывания слайдера/управления всеми элементами контента, а не вышеприведенным повторением слайдеров:

 <slider> - 2021   </slider>
<section class= "container-of-all-items">
<all-items></all-items>
</section>
 

Есть идеи, как этого достичь, сохранив карту через Slices ?

Комментарии:

1. Что такое данные на первой карте data.map?

Ответ №1:

Я вижу, мне потребовалось некоторое время, чтобы понять, что вы в основном хотите иметь один набор и — но списка предметов.

Тогда в вашем случае код действительно упрощается.

 function Lists() {
  const { dates, setDates } = React.useContext(DateContext);
  const onClick = () => { setDates(...) }

  return (
    <>
      <div onClick={onClick}> </div>
      <>
        {dates.map((item, index) => {
          return <Slice section={item.section} key={index} />
        })}
      </>
      <div>-</div>
    </div>
  );
}
 

Затем измените свое приложение.

 export default function App() {
  return (
    <div className="App">
      <DatesProvider value={...}>
         <Lists />
      </DatesProvider>
    </div>
  );
}
 

На самом деле вам может вообще не понадобиться контекст, так как логика была передана родителю. Но это зависит от тебя.