javascript - ประเภท '{ children: Element; }' ไม่มีคุณสมบัติใดที่เหมือนกับประเภท 'IntrinsicAttributes' - React 18.2.0
ฉันมีคำถาม ฉันกำลังเรียน React กับ TypeScript โดยใช้หนังสือเรียน - fullstack react with typescript ตอนนี้ฉันอยู่ที่แอปแรก - การโคลน Trello
ฉันเจอบั๊กที่ฉันกำลังหาวิธีแก้ไขได้ยาก
ฉันได้รับข้อผิดพลาดนี้จาก AppStateContext
Type '{ children: Element; }' has no properties in common with type 'IntrinsicAttributes'นี่คือบล็อกที่มันถูกกำหนด: AppStateContext.tsx
export const AppStateProvider: FC = ({ children }: React.PropsWithChildren<{}>) => {
const [state, dispatch] = useImmerReducer(appStateReducer, appData)
const { lists } = state
const getTasksByListId = (id: string) => {
return lists.find((list) => list.id === id)?.tasks || []
}
return (
<AppStateContext.Provider value={{ lists, getTasksByListId, dispatch }}>
{children}
</AppStateContext.Provider>
)
}
นี่คือบล็อกที่ถูกเรียก: index.tsx
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<AppStateProvider>
<App />
</AppStateProvider>
);
ข้อผิดพลาดเกิดจากที่ฉันเรียกในไฟล์ index.tsx
ฉันขอบคุณสำหรับความช่วยเหลือล่วงหน้าเป็นอย่างมาก เวอร์ชันของ React คือ 18.2.0
คำตอบ #1
คุณจำเป็นต้องลบประเภท FC ที่ชัดเจนสำหรับ AppStateProvider ออก
ดูตัวอย่างที่ทำให้เข้าใจง่ายนี้:
interface FunctionComponent<P = {}> {
(props: P, context?: any): ReactElement<any, any> | null;
}
อย่างที่คุณอาจสังเกตเห็น, FunctionComponent เป็นเวอร์ชันที่เรียบง่ายขึ้น (ลบ props ที่ไม่เกี่ยวข้องกับคำถามของคุณออก) ของ FC.
Generic P แทนค่าอาร์กิวเมนต์ props หาก generic P ไม่มี property children คุณจะไม่สามารถใช้มันได้ แท้จริงแล้วคุณสามารถใช้ได้เฉพาะ property ที่ประกาศใน generic P เท่านั้น
โปรดทราบว่าคุณได้ใช้เพียง FC ซึ่งหมายความว่า P generic ถูกแทนที่ด้วย {} ดังนั้นคุณจะไม่สามารถให้คุณสมบัติใด ๆ กับคอมโพเนนต์ React ได้
ดูนี่:
type Fn<P = 'no properties'> = (props: P) => void
const fn: Fn = (props) => {
props // no properties
}
props มีชนิด 'no properties' และคุณไม่อนุญาตให้แทนที่ด้วยชนิดอื่น:
// errpr
const fn: Fn = (props:number) => {
props // no properties
}
ตัวอย่างของคุณค่อนข้างแตกต่าง เพราะประเภทของ TypeScript {} เป็นประเภทที่ซับซ้อน เนื่องจากทุกอย่างใน JavaScript เป็น object ประเภทใด ๆ (ไม่แน่ใจ 100%) สามารถกำหนดค่าให้กับ {} ได้ นี่คือเหตุผลที่คุณไม่พบข้อผิดพลาดเมื่อใช้ React.PropsWithChildren<{}> สำหรับ props อย่างไรก็ตาม การใช้ React.PropsWithChildren<{}> จะไม่ส่งผลกระทบต่อประเภท AppStateProvider เพราะเมื่อคุณเรียกใช้ มันจะคาดหวังเพียง {} เป็น properties เท่านั้น
โดยเป็นกฎทั่วไป คุณสามารถใช้ทั้งชนิดของฟังก์ชันทั้งหมดอย่างชัดเจนและหลีกเลี่ยงการใช้ชนิดของอาร์กิวเมนต์ หรือเพียงแค่ใช้ชนิดสำหรับอาร์กิวเมนต์เท่านั้น
อันนี้ก็ได้:
type Fn<P = 'no properties'> = (props: P) => void
const fn: Fn = (props) => {
props // no properties
}
หรือ
const fn = (props:'no properties') => {
props // no properties
}
ป.ล. ใน React 17.*, FC มี children type ดูบทความนี้
คำตอบ #2
ข้อผิดพลาดโดยพื้นฐานแล้วบอกคุณว่าประเภทของ children (ซึ่งคือ Elements) ไม่มีการทับซ้อนกับประเภทที่คุณกำหนดใน TypeScript (React.PropsWithChildren<{}>) วิธีที่ง่ายในการแก้ปัญหาคือการเปลี่ยนไฟล์ AppStateContext.tsx เป็นอะไรทำนองนี้:
export const AppStateProvider: FC = ({ children }: {children:Elements) => {
...
อย่างไรก็ตาม ถ้าคุณต้องการฝึกฝนการเขียนโค้ดที่สะอาดจริง ๆ และใช้ React.PropsWithChildren นี่คือตัวเก็บข้อมูลพร้อมตัวอย่างการใช้งาน: https://github.com/KishorNaik/Sol_PropsWithChildren_React
หวังว่านี่จะช่วยได้
