Saya memiliki array objek ini di proyek kalender saya:

const [selectedDay, setSelectedDay] = useState({});

const [weekday,setWeekDays] = useState([ 
  {name: 'Su',sortedDays:[{dayNum:1,chosen:false}]},
  {name: 'Mo',sortedDays:[{dayNum:21,chosen:false}},
  {name: 'Tu',sortedDays:[{dayNum:15,chosen:false}},
  {name: 'We',sortedDays:[{dayNum:11,chosen:false}},
  {name: 'Th',sortedDays:[{dayNum:23,chosen:false}},
  {name: 'Fr',sortedDays:[{dayNum:31,chosen:false}},
  {name: 'Sa',sortedDays:[{dayNum:30,chosen:false}},
])

Apa yang saya lakukan

Saya memetakan array ini sebagai tombol dan memberi pengguna kemampuan untuk memilih hari di kalender

Apa yang saya coba capai

Setiap kali pengguna mengklik tombol, tombol yang dipilih harus mengubah warna latar belakang.

Yang saya coba

Pertama saya mencoba membuat ini berfungsi seperti ini:

const selectWeekDay = (child, info) => {
const updateSortedDays = info.sortedDays.map((day) =>
  day.dayNum === child.dayNum
    ? {...day, chosen: !day.chosen}
    : {...day, chosen: false},
);

const updatedWeekDay = weekday.map((el) => {
  return el.name === info.name ? {...el, sortedDays: updateSortedDays} : el;
});

setWeekDays(updatedWeekDay);
};

Dan itu berhasil tetapi masalahnya adalah itu tidak berfungsi pada setiap array di dalam array objek saya.

Jadi saya mencoba mengubahnya seperti ini:

 const updateWeekDays = () => {
let x = [...weekday];
for (let i = 0; i < x.length; i++) {
  x[i].sortedDays.map((day) =>
    selectedDay.dayNum === day.dayNum
      ? {...day, chosen: true}
      : {...day, chosen: false},
  );
}
return x;
};

Saya memanggil fungsi ini di useEffect hanya setelah validasi ini:

useEffect(() => {
if (selectedDay.dayNum) {
  setWeekDays(updateWeekDays());
}
  }, [selectedDay]);

Tapi sayangnya solusi ini tidak berhasil dan saya tidak mengerti mengapa.

Ada saran?

DEMO:

https://replit.com/@NikitaZotsik/MultipleArrayMap#index.js

0
user14587589 12 Mei 2021, 14:31

2 jawaban

Jawaban Terbaik

Coba ubah fungsi updateWeekDays Anda seperti di bawah ini:-

  const updateWeekDays = () => {
    const copyWeekDay = [...weekday];
    return copyWeekDay.map(week => {
      week.sortedDays = week.sortedDays.map(day => {
        if (day.dayNum === selectedDay.dayNum) {
          day.chosen = !day.chosen;
        }
        return day;
      });
      return week;
    });
  };
0
Wai Ha Lee 12 Mei 2021, 17:53
const {
  useState,
  useEffect
} = React


const App = () => {
  const chooseDay = (days, dayName) => {
    const result = [...days]
    result.forEach(day => day.sortedDays[0].chosen = false);
    const dayToChange = result.find(({ name }) => name === dayName)
    dayToChange.sortedDays[0].chosen = true;
    return result;
  }
  const [weekDays,setWeekDays] = useState([ 
    {name: 'Su',sortedDays:[{dayNum:1,chosen:false}]},
    {name: 'Mo',sortedDays:[{dayNum:21,chosen:false}]},
    {name: 'Tu',sortedDays:[{dayNum:15,chosen:false}]},
    {name: 'We',sortedDays:[{dayNum:11,chosen:false}]},
    {name: 'Th',sortedDays:[{dayNum:23,chosen:false}]},
    {name: 'Fr',sortedDays:[{dayNum:31,chosen:false}]},
    {name: 'Sa',sortedDays:[{dayNum:30,chosen:false}]},
  ])

  return <div>
    {weekDays.map(
      ({ name, sortedDays: [{dayNum, chosen}] }) => 
        <button
          key={name}
          style={{ backgroundColor: chosen && 'green' }} 
          onClick={() => setWeekDays(chooseDay(weekDays, name))}>
          { name }
        </button>  
    )}
    </div>
}

ReactDOM.render( < App / > , app);
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<div id=app>
0
bel3atar 12 Mei 2021, 12:22