useContext()

Η βασική ιδέα είναι ότι με τη hook συνάρτηση useContext() μπορούμε να περάσουμε σε ένα σύνολο από παιδιά (σε όποιο επίπεδο) μία ή περισσότερες παραμέτρους (props) με έναν πιο σύντομο και εύκολο τρόπο.

Πιο απλά, μπορείτε να θεωρήσετε ότι με την useContext() δηλώνουμε μια global μεταβλητή στην οποία μπορούν να έχουν πρόσβαση τα components ανεξάρτητα της θέσης τους.

Στο παρακάτω παράδειγμα φαίνεται πως δηλώνεται και καλείται μια useContext μεταβλητή

import { createContext, useContext } from 'react';

const StyleContext = createContext({color: "green", backgroundColor: "yellow"});

function Button({children}) {
  const style = useContext(StyleContext);
  return (
    <button style = {style} >{children}</button>
  );
}

export default function App() {
  return (
    <nav>
        <Button>Home</Button>
        <Button>Services</Button>
        <Button>About</Button>
        <Button>FAQ</Button>
        <Button>Contact</Button>
    </nav>
  );
}

Μπορούμε να έχουμε και να χρησιμοποιούμε περισσότερες από μία useContext μεταβλητές.

import { createContext, useContext } from 'react';

const NormalMode = createContext({color: "black", backgroundColor: "lightgray"});
const ActiveMode = createContext({color: "green", backgroundColor: "white"});

function Button({active = false, children}) {
  const style = useContext((active) ? ActiveMode : NormalMode);
  return (
    <button style = {style} >{children}</button>
  );
}

export default function App() {
  return (
    <nav>
        <Button active = {true}>Home</Button>
        <Button>Services</Button>
        <Button>About</Button>
        <Button>FAQ</Button>
        <Button>Contact</Button>
    </nav>
  );
}

Για να ισχύουν διαφορετικές τιμές για μια useContext μεταβλητή, χρησιμοποιούμε ένα Provider σε συνδυασμό με την ειδική ιδιότητα value όπως στο παράδειγμα.

import { createContext, useContext } from 'react';

const ThemeContext = createContext({color: "red", backgroundColor: "blue"});

function Button({children}) {
  const style = useContext(ThemeContext);
  return (
    <button style = {style} >{children}</button>
  );
}

export default function App() {
  return (
    <nav>
        <Button>Home</Button>
        <Button>Services</Button>
      <ThemeContext.Provider value= {{color: "blue", backgroundColor: "red"}}>
        <Button>About</Button>
        <Button>FAQ</Button>
        <Button>Contact</Button>
      </ThemeContext.Provider>
    </nav>
  );
}

Μπορούμε να έχουμε useContext μεταβλητές που γίνονται overriden.

import { createContext, useContext } from 'react';

const ThemeContext = createContext(null);

function Button({children}) {
  const style = useContext(ThemeContext);
  return (
    <button style = {style} >{children}</button>
  );
}

export default function App() {
  return (
    <nav>
        <ThemeContext.Provider value= {{color: "blue", backgroundColor: "red"}}>
            <ThemeContext.Provider value= {{color: "red", backgroundColor: "blue"}}>
                <Button>Home</Button>
            </ThemeContext.Provider>
            <Button>Services</Button>
            <Button>About</Button>
            <Button>FAQ</Button>
            <Button>Contact</Button>
        </ThemeContext.Provider>
    </nav>
  );
}

Στο παρακάτω παράδειγμα φαίνεται πως η πρόσβαση στη useContext μεταβλητή μπορεί να γίνει από component σε διαφορετικό "βάθος".

import { createContext, useContext } from 'react';

const StyleContext = createContext({color: "green", backgroundColor: "yellow"});

function Button({children}) {
  const style = useContext(StyleContext);
  return (
    <button style = {style} >{children}</button>
  );
}

function ButtonRow({children}) {
    return (
        <>
            <Button>{children[0]}</Button>
            <Button>{children[1]}</Button>
        </>
    );
}

export default function App() {
  return (
    <nav>
      <ButtonRow>{["Home", "Services"]}</ButtonRow>

      <StyleContext.Provider value = {{color: "blue", backgroundColor: "red"}}>
        <ButtonRow>{["About", "FAQ"]}</ButtonRow>
      </StyleContext.Provider>
      
      <Button>Contact</Button>
    </nav>
  );
}

Μπορείτε να συνδυάσετε μια useContext μεταβλητή με μια useState έτσι ώστε να έχουμε rerender όταν χρειάζεται.

import { useState, createContext, useContext } from 'react';

const ThemeContext = createContext(null);

function ToggleButton({onClick, children}) {
    return (
        <button onClick = {onClick} >{children}</button>
      );
}

function Button({children}) {
  const theme = useContext(ThemeContext);
  return (
    <button className = {theme} >{children}</button>
  );
}

export default function App() {
    const [theme, setTheme] = useState("light");

    function handleToggle() {
        setTheme((theme === "light") ? "dark" : "light");
    }
    return (
    <nav>
        <ThemeContext.Provider value= {theme}>
            <Button>Home</Button>
            <Button>Services</Button>
            <Button>About</Button>
            <Button>FAQ</Button>
            <Button>Contact</Button>
        </ThemeContext.Provider>
        <ToggleButton onClick = {handleToggle}>Toggle Mode</ToggleButton>
    </nav>
  );
}

Μπορείτε να αποθηκεύσετε μια useContext μεταβλητή σε εξωτερικό αρχείο και να καλείται από διαφορετικά components.

import { createContext} from 'react';
export const ThemeContext = createContext({color: "red", backgroundColor: "blue"});