ค้นหาเว็บไซต์

javascript - วิธีการใช้ "useContext" ใน typescript?


ฉันกำลังพยายามสร้างระบบธีมมืด/สว่างในโปรเจกต์ของฉัน แต่ฉันกำลังมีปัญหาบางอย่างกับโค้ด

บรรทัดโค้ดนี้ทำงานได้ดีในจาวาสคริปต์:

const [darktheme, setDarkTheme] = useContext(ThemeContext);

แต่เมื่อฉันเขียนมันเป็นไทป์สคริปต์ ฉันได้รับข้อผิดพลาด 6 ข้อ

ฉันรู้ว่าตัวแปรบางตัวต้องมีการประกาศประเภท แต่ฉันรู้แค่ประเภทของตัวแปร darkTheme ซึ่งเป็นบูลีน

หลังจากที่ฉันประกาศประเภทแล้ว ข้อผิดพลาด 2 อย่างหายไป แต่ยังคงมีข้อผิดพลาด 4 อย่างอยู่!

const [darktheme: boolean, setDarkTheme: any] = useContext(ThemeContext);

ฉันใช้ any หลังจากธีมสีเข้ม ซึ่งไม่ใช่การปฏิบัติที่ดี แต่ฉันไม่รู้ประเภท

ตอนนี้ฉันก็เจอข้อผิดพลาดเหล่านี้:

ฉันคิดว่าปัญหาหลักกับโครงการของฉันคือฉันกำลังพยายามรวม JavaScript กับ TypeScript ฉันไม่แน่ใจว่านั่นเป็นเรื่องปกติหรือไม่ แต่ฉันทำแบบนี้เพราะบางส่วนประกอบง่ายกว่าที่จะเขียนด้วย TypeScript และบางส่วนประกอบพื้นฐานดีกว่าที่จะเขียนด้วย JavaScript

นี่คือส่วนหนึ่งของไฟล์ app.js ของฉัน:

// Context

export const ThemeContext = React.createContext();

function App() {
  const [darkTheme, setDarkTheme] = useState(false);

  return (
    <ThemeContext.Provider value={[darkTheme, setDarkTheme]}>

,และเมื่อฉันใช้ฟังก์ชันในคอมโพเนนต์นี้ มันทำงานได้ดีตามปกติ:

import React, { useContext } from 'react';
import { ThemeContext } from '../App';

import Button from 'react-bootstrap/Button';

export default function DarkThemeTest() {
    const [darktheme, setDarkTheme] = useContext(ThemeContext);

    return (
        <Button onClick={() => {
            setDarkTheme(!darktheme);
        }}>
            Theme: {darktheme && "Dark" || "Light"}
        </Button>
    )
}

คำตอบ #1

ก่อนอื่น กำหนดประเภทสำหรับค่าบริบทของคุณ

import { createContext, Dispatch, SetStateAction } from "react";

interface ThemeContextType {
  darkTheme: boolean;

  // this is the type for state setters
  setDarkTheme: Dispatch<SetStateAction<boolean>>; 
}

จากนั้น สร้างคอนเท็กซ์ของคุณด้วยประเภทนี้และเริ่มต้นด้วยค่าดีฟอลต์ นี่อาจดูไม่จำเป็น แต่จะช่วยหลีกเลี่ยงการตรวจสอบคอนเท็กซ์ที่เป็น null หรือ undefined ในภายหลัง

export const ThemeContext = createContext<ThemeContextType>({
  darkTheme: false,
  setDarkTheme: () => {}, // no-op default setter
});

เมื่อคุณสร้างค่ารัฐและฟังก์ชันตั้งค่าแล้ว ให้ตั้งค่าพวกมันลงในค่าผู้ให้บริบท

<ThemeContext.Provider value={{ darkTheme, setDarkTheme }}>

ตอนนี้คุณสามารถแยกค่าของ context ได้อย่างง่ายดายผ่าน useContext พร้อมการสนับสนุนประเภทเต็มรูปแบบ

const { darkTheme, setDarkTheme } = useContext(ThemeContext);

คุณยังสามารถใช้รูปแบบอาร์เรย์ของคุณต่อไปได้แม้ว่าฉันจะไม่แนะนำก็ตาม

type ThemeContextType = [boolean, Dispatch<SetStateAction<boolean>>];

export const ThemeContext = createContext<ThemeContextType>([false, () => {}]);

และ

<ThemeContext.Provider value={[darkTheme, setDarkTheme]}>