【发布时间】:2022-01-11 19:57:03
【问题描述】:
各位开发者您好,
我是初级开发人员,我正在开发一个包含大型嵌套对象(示例如下)的项目,理想情况下我想将其用作可以从多个地方访问的反应状态,但我不知道哪种方法最好对于这个解决方案,因为我还没有很多经验。如果您能给我一些建议、代码示例或一些教程或博客的链接,那将非常有帮助。
我目前的方法(下面的示例)是使用 useContext without useReducer 因为我只是不想只导出调度,因为我认为有点丑陋或对程序员不友好,因为你总是必须定义不同的类型和有效载荷。也许我可以将 dispatch 它包装在函数中,但我只是不确定。我也在考虑使用 Redux,但我还没有使用它,根据读到的内容,这可能是矫枉过正。
提前谢谢你。
{
id: string,
name: string,
sections: [{
id: string,
pos_x: number,
pos_y: number,
rows: number,
columns: number,
curvature: number,
skew: number,
rotation: number,
section_type: string,
name: string,
seats: [{
id: string,
row: number,
column: number,
is_disabled: boolean,
category: string,
name: string,
created_at: string,
updated_at: string,
is_reserved: boolean,
reserved_at: string,
status: string,
ticket: number
}],
total_seats: number,
created_at: string,
updated_at: string,
available_seats: number,
purchased_seats: number,
reserved_seats: number
}],
creator: number,
account: number,
is_editable: boolean,
total_seats: number,
created_at: string,
updated_at: string,
event: number,
available_seats: number,
purchased_seats: number,
reserved_seats: number
}
import React, {createContext, FC, useState} from 'react';
import {Seat, SeatMap, Section} from "../../types/seatmapData";
type UpdateSelectedSectionProps = (section: Section, seatIndex: number) => Section
export interface ISeatMap {
id: string,
name: string,
sections: Section[],
creator: number,
account: number,
isEditable: boolean,
totalSeats: number,
createdAt: string,
updatedAt: string,
event: number,
availableSeats: number,
purchasedSeats: number,
reservedSeats: number
}
export interface ISeatMapContext extends ISeatMap {
setName: (name: string) => void;
setSections: (section: Section[]) => void;
setId: (id: string) => void;
setCreator: (creator: number) => void;
setAccount: (account: number) => void;
setIsEditable: (isEditable: boolean) => void;
setTotalSeats: (totalSeats: number) => void;
setCreatedAt: (createdAt: string) => void;
setUpdatedAt: (updatedAt: string) => void;
setEvent: (event: number) => void;
setAvailableSeats: (availableSeats: number) => void;
setPurchasedSeats: (purchasedSeats: number) => void;
setReservedSeats: (reservedSears: number) => void;
addSectionToSelected: (section: Section) => void;
removeSectionsFromSelected: (section: Section) => void;
clearSelectedSections: () => void;
addSeatToSelected: (section: Section, seat: Seat) => void;
removeSeatFromSelected: (section: Section, seat: Seat) => void;
clearSelectedSeats: () => void;
addSection: (section: Section) => void;
removeSection: (section: Section) => void;
removeSelectedSections: () => void;
updateSection: (section: Section) => void;
updateSelectedSeats: (updateFunction: UpdateSelectedSectionProps) => boolean;
reserveSelectedSeats: (reserved: boolean, reservedAt: Date) => void;
purchaseSelectedSeat: () => void;
disableSelectedSeats: (disabled: boolean) => void;
getSeatMap: () => void;
}
export const SeatMapContext = createContext<ISeatMapContext>(null!);
export interface SeatMapProviderProps extends FC {
children: any;
initialValue: SeatMap;
}
const SeatMapProvider = ({ children, initialValue }: SeatMapProviderProps) => {
const [name, setName] = useState<string>(initialValue.name)
const [sections, setSections] = useState<Section[]>(initialValue.sections)
const [id, setId] = useState<string>(initialValue.id)
const [creator, setCreator] = useState<number>(initialValue.creator)
const [account, setAccount] = useState<number>(initialValue.account)
const [isEditable, setIsEditable] = useState<boolean>(initialValue.is_editable)
const [totalSeats, setTotalSeats] = useState<number>(initialValue.total_seats)
const [createdAt, setCreatedAt] = useState<string>(initialValue.created_at)
const [updatedAt, setUpdatedAt] = useState<string>(initialValue.updated_at)
const [event, setEvent] = useState<number>(initialValue.event)
const [availableSeats, setAvailableSeats] = useState<number>(initialValue.available_seats)
const [purchasedSeats, setPurchasedSeats] = useState<number>(initialValue.purchased_seats)
const [reservedSeats, setReservedSeats] = useState<number>(initialValue.reserved_seats)
const [selectedSections, setSelectedSections] = useState<Section[]>([]);
const [selectedSeats, setSelectedSeats] = useState<{section: Section, seat: Seat}[]>([]);
const addSectionToSelected = (section: Section) => {
setSelectedSections(prev => [...prev, section])
}
const removeSectionsFromSelected = (section: Section) => {
setSelectedSections(prev => prev.filter(s => s.id === section.id))
}
const clearSelectedSections = () => {
setSelectedSections([])
}
const addSeatToSelected = (section: Section, seat: Seat) => {
setSelectedSeats(prev => [...prev, {section: section, seat: seat}])
}
const removeSeatFromSelected = (section: Section, seat: Seat) => {
setSelectedSeats(prev => prev.filter(s => s.section.id === section.id && s.seat.id == seat.id))
}
const clearSelectedSeats = () => {
setSelectedSeats([])
}
const addSection = (section: Section) => {
setSections(prevState => [...prevState, section])
}
const removeSection = (section: Section) => {
setSections(prevState => prevState.filter(s => s.id == section.id))
}
const removeSelectedSections = () => {
if(selectedSections.length == 0) return
setSections(prevState => {
const notSelected: Section[] = []
prevState.forEach(s => {
let isSelected = false
selectedSections.forEach(selected => {
if(selected.id == s.id) isSelected = true
})
if(!isSelected) notSelected.push(s)
})
return notSelected
})
}
const updateSection = (section: Section) => {
setSections((prevState) => {
const index = prevState.findIndex(s => s.id === section.id)
sections[index] = section
return sections
})
}
const updateSelectedSeats = (updateFunction: UpdateSelectedSectionProps): boolean => {
if(selectedSections.length == 0 || selectedSeats.length == 0) return false
const updateTime = new Date().toISOString()
setSections(sections => {
selectedSeats.forEach(({section, seat}) => {
const sectionIndex = sections.findIndex(s => s.id === section.id)
const seatIndex = sections[sectionIndex].seats.findIndex(s => s.id === seat.id)
const newSection = updateFunction(sections[sectionIndex], seatIndex);
sections[sectionIndex] = newSection
sections[sectionIndex].updated_at = updateTime
})
return sections
})
setUpdatedAt(updateTime)
return true
}
const reserveSelectedSeats = (reserved: boolean, reservedAt: Date) => {
const updated = updateSelectedSeats((section, seatIndex) => {
section.seats[seatIndex].is_reserved = reserved
section.seats[seatIndex].reserved_at = reservedAt.toISOString()
return section
})
if(updated) setReservedSeats(prev => reserved ? ++prev : --prev)
}
const purchaseSelectedSeat = () => {
}
const disableSelectedSeats = (disabled: boolean) => {
const updated = updateSelectedSeats((section, seatIndex) => {
section.seats[seatIndex].is_disabled = disabled
if(disabled) section.total_seats--
else section.total_seats++
return section
})
if(updated) setTotalSeats(prev => disabled ? --prev : ++prev)
}
const getSeatMap = (): SeatMap => {
return {
name: name,
sections: sections,
id: id,
creator: creator,
account: account,
is_editable: isEditable,
total_seats: totalSeats,
created_at: createdAt,
updated_at: updatedAt,
event: event,
available_seats: availableSeats,
purchased_seats: purchasedSeats,
reserved_seats: reservedSeats,
}
}
return (
<SeatMapContext.Provider value={{
name, setName,
sections, setSections,
id, setId,
creator, setCreator,
account, setAccount,
isEditable, setIsEditable,
totalSeats, setTotalSeats,
createdAt, setCreatedAt,
updatedAt, setUpdatedAt,
event, setEvent,
availableSeats, setAvailableSeats,
purchasedSeats, setPurchasedSeats,
reservedSeats, setReservedSeats,
addSectionToSelected,
addSeatToSelected,
clearSelectedSeats,
clearSelectedSections,
purchaseSelectedSeat,
removeSeatFromSelected,
removeSectionsFromSelected,
getSeatMap,
addSection,
removeSection,
updateSection,
removeSelectedSections,
updateSelectedSeats,
reserveSelectedSeats,
disableSelectedSeats
}}>
{children}
</SeatMapContext.Provider>
)
};
export default SeatMapProvider;
【问题讨论】:
标签: javascript reactjs typescript react-redux react-hooks