Ինչպես օգտագործել React համատեքստը պետական կառավարման համար Next.js 13-ում


React-ի ներկառուցված Context API-ն կատարյալ է վիճակի փոխանակման համար: Իմացեք, թե ինչպես օգտագործել այն Next.js-ի վերջին տարբերակի հետ:

Next.js-ն առաջարկում է պետական կառավարման մի քանի մոտեցում: Թեև այս մեթոդներից որոշները պահանջում են նոր գրադարանների տեղադրում, React-ի համատեքստային API-ն ներկառուցված է, ուստի այն արտաքին կախվածությունները նվազեցնելու հիանալի միջոց է:

React Context-ի միջոցով դուք կարող եք անխափան կերպով տվյալներ փոխանցել ձեր բաղադրիչ ծառի տարբեր մասերով՝ վերացնելով հենակետային հորատման դժվարությունները: Սա հատկապես օգտակար է գլոբալ վիճակի կառավարման համար, ինչպիսին է ներկայիս օգտվողի մուտքի կարգավիճակը կամ նախընտրած թեման:

Հասկանալով React Context API-ն

Նախքան կոդի մեջ խորանալը, կարևոր է հասկանալ, թե ինչ է React Context API-ն և ինչ խնդիր է այն լուծում:

Props-ը արդյունավետ մեթոդ է ապահովում բաղադրիչների միջև տվյալների փոխանակման համար: Նրանք թույլ են տալիս փոխանցել տվյալներ մայր բաղադրիչից նրա զավակ բաղադրիչներին:

Այս մոտեցումը օգտակար է, քանի որ այն հստակ ցույց է տալիս, թե որ բաղադրիչներն են օգտագործում որոշակի տվյալներ և ինչպես են այդ տվյալները հոսում բաղադրիչի ծառից:

Այնուամենայնիվ, խնդիրներ են առաջանում, երբ դուք ունեք խորը ներկառուցված բաղադրիչներ, որոնք պետք է սպառեն նույն հենարանները: Այս իրավիճակը կարող է առաջացնել բարդություններ և կարող է հանգեցնել խճճված կոդի, որն ավելի դժվար է պահպանել: Այս խնդիրները, ի թիվս այլոց, հենակետային հորատման թերություններն են:

React Context-ը լուծում է այս մարտահրավերը՝ տրամադրելով կենտրոնացված մեթոդ՝ ստեղծելու և օգտագործելու տվյալները, որոնք պետք է հասանելի լինեն գլոբալ մասշտաբով, բաղադրիչների միջև:

Այն ստեղծում է համատեքստ այս տվյալները պահելու համար՝ թույլ տալով բաղադրիչներին մուտք գործել դրանք: Այս մոտեցումը օգնում է ձեզ կառուցապատել ձեր կոդերի բազան՝ ապահովելու համար, որ այն լավ կազմակերպված է:

Դուք կարող եք գտնել այս նախագծի կոդը նրա GitHub պահոցում:

Ինչպես սկսել State Management-ում Next.js 13-ում, օգտագործելով React Context API-ն

Next.js Server Components-ը թույլ է տալիս ստեղծել հավելվածներ, որոնք լավագույնս կօգտագործեն երկու աշխարհներից՝ հաճախորդի կողմի հավելվածների ինտերակտիվությունը և սերվերի մատուցման արդյունավետության առավելությունները:

Next.js 13-ը լռելյայնորեն իրականացնում է սերվերի բաղադրիչները app գրացուցակում, որն այժմ կայուն է: Այնուամենայնիվ, քանի որ բոլոր բաղադրիչները մատուցվում են սերվերի կողմից, դուք կարող եք խնդիրներ ունենալ հաճախորդի կողմից գրադարանների կամ API-ների ինտեգրման ժամանակ, ինչպիսիք են React Context-ը:

Սրանից խուսափելու համար հիանալի լուծում է օգտագործել հաճախորդը դրոշը, որը դուք կարող եք սահմանել ֆայլերի վրա, որոնք կգործարկեն հաճախորդի կողմի կոդը:

Սկսելու համար ստեղծեք Next.js 13 նախագիծ տեղական մակարդակում՝ գործարկելով այս հրամանը ձեր տերմինալում.

npx create-next-app@latest next-context-api

Նախագիծը ստեղծելուց հետո անցեք նրա գրացուցակ.

cd next-context-api

Այնուհետև գործարկեք զարգացման սերվերը.

npm run dev

Երբ ստեղծեք հիմնական Next.js նախագիծը, կարող եք ստեղծել հիմնական անելիքների հավելված, որն օգտագործում է React Context API-ն պետական կառավարման համար:

Ստեղծեք համատեքստի մատակարարը

Համատեքստի մատակարարի ֆայլը ծառայում է որպես կենտրոնական հանգույց, որտեղ դուք սահմանում և կառավարում եք գլոբալ վիճակը, որին բաղադրիչները պետք է հասանելի լինեն:

Ստեղծեք նոր ֆայլ՝ src/context/Todo.context.js և լրացրեք այն հետևյալ կոդով։

"use client"
import React, { createContext, useReducer } from "react";
const initialState = {
  todos: [],
};
const reducer = (state, action) => {
  switch (action.type) {
    case "ADD_TODO":
      return { ...state, todos: [...state.todos, action.payload] };
    case "DELETE_TODO":
      return { ...state, todos: state.todos.filter((todo, index) => 
               index !== action.payload) };
    case "EDIT_TODO":
      const updatedTodos = state.todos.map((todo, index) => 
               index === action.payload.index ? action.payload.newTodo : todo);
      return { ...state, todos: updatedTodos };
    default:
      return state;
  }
};
export const TodoContext = createContext({
  state: initialState,
  dispatch: () => null,
});
export const TodoContextProvider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <TodoContext.Provider value={{ state, dispatch }}>
      {children}
    </TodoContext.Provider>
  );
};

Այս React Context կարգավորումը սահմանում է TodoContext, որն ի սկզբանե պահում է հավելվածի դատարկ անելիքների ցուցակի վիճակը:

Բացի սկզբնական վիճակի ստեղծումից, այս համատեքստի կոնֆիգուրացիան ներառում էreducer ֆունկցիա, որը սահմանում է գործողությունների տարբեր տեսակներ: Գործողությունների այս տեսակները կփոփոխեն համատեքստի վիճակը՝ կախված գործարկվող գործողություններից: Այս դեպքում գործողությունները ներառում են անելիքների ավելացում, ջնջում և խմբագրում:

TodoContextProvider բաղադրիչն ապահովում է TodoContext հավելվածի այլ բաղադրիչներին: Այս բաղադրիչը վերցնում է երկու հենարան՝ արժեքի հենարան, որը համատեքստի սկզբնական վիճակն է, և ռեդուկտորի հենարան, որը ռեդուկտորի ֆունկցիան է։

Երբ բաղադրիչը սպառում է TodoContext-ը, այն կարող է մուտք գործել համատեքստի վիճակ և ուղարկել գործողություններ՝ վիճակը թարմացնելու համար:

Համատեքստի մատակարարին ավելացրեք Next.js հավելվածին

Այժմ, որպեսզի համոզվեք, որ համատեքստի մատակարարը ցուցադրում է ձեր Next.js հավելվածի հիմքում, և որ հաճախորդի բոլոր բաղադրիչները կարող են մուտք գործել դրան, դուք պետք է համատեքստն ավելացնեք հավելվածի հիմնական դասավորության բաղադրիչին:

Դա անելու համար բացեք src/app/layout.js ֆայլը և փաթեթավորեք մանկական հանգույցը HTML ձևանմուշում համատեքստի մատակարարի հետ հետևյալ կերպ.

import './globals.css';
import { TodoContextProvider } from "@/context/Todo.context";
export const metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};
export default function RootLayout({
  children
}) {
  return (
    <html lang="en">
      <body>
        <TodoContextProvider>{children}</TodoContextProvider>
      </body>
    </html>
  );
}

Ստեղծեք անելիքների բաղադրիչ

Ստեղծեք նոր ֆայլ՝ src/components/Todo.js և դրան ավելացրեք հետևյալ կոդը։

Սկսեք կատարել հետևյալ ներմուծումները. Համոզվեք, որ ներառեք օգտագործել հաճախորդը դրոշը՝ այս բաղադրիչը որպես հաճախորդի կողմից բաղադրիչ նշելու համար:

"use client"
import { TodoContext } from "@/context/Todo.context";
import React, { useContext, useState } from "react";

Հաջորդը, սահմանեք ֆունկցիոնալ բաղադրիչը, ներառյալ JSX տարրերը, որոնք կարտացոլվեն դիտարկիչում:

export default function Todo() {
  return (
    <div style={{ marginBottom: "4rem", textAlign: "center" }}>
      <h2>Todos</h2>
      <input
        type="text"
        value={todoText}
        onChange={(e) => setTodoText(e.target.value)}
        style={{ marginBottom: 16}}
        placeholder="Enter a todo"
      />
      <button onClick={handleAddTodo}>Add Todo</button>
      <ul>
        {state.todos.map((todo, index) => (
          <li key={index}>
            {index === editingIndex ? (
              <>
                <input
                  type="text"
                  value={editedTodo}
                  onChange={(e) => setEditedTodo(e.target.value)}
                />
                <button 
                  style={{ marginRight: 16}} 
                  onClick={() => handleEditTodo(index, editedTodo)}
                >
                    Save
                </button>
              </>
            ) : (
              <>
                {todo}
                <button 
                  style={{ marginRight: 16}} 
                  onClick={() => setEditingIndex(index)}
                >Edit</button>
                <button 
                  onClick={() => handleDeleteTodo(index)}
                >Delete</button>
              </>
            )}
          </li>
        ))}
      </ul>
    </div>
  );
}

Այս ֆունկցիոնալ բաղադրիչը ներառում է մուտքագրման դաշտեր՝ ավելացնելու, խմբագրելու և ջնջելու անելիքները՝ համապատասխան կոճակների հետ միասին: Այն օգտագործում է React-ի պայմանական վերարտադրությունը՝ խմբագրման ինդեքսի արժեքի հիման վրա խմբագրման և ջնջման կոճակները ցուցադրելու համար։

Վերջապես, սահմանեք պահանջվող վիճակի փոփոխականները և պահանջվող կարգավորիչի գործառույթները յուրաքանչյուր գործողության տեսակի համար: Գործառույթի բաղադրիչի ներսում ավելացրեք հետևյալ կոդը.

  const { state, dispatch } = useContext(TodoContext);
  const [todoText, setTodoText] = useState("");
  const [editingIndex, setEditingIndex] = useState(-1);
  const [editedTodo, setEditedTodo] = useState("");
  const handleAddTodo = () => {
    if (todoText.trim() !== "") {
      dispatch({ type: "ADD_TODO", payload: todoText });
      setTodoText("");
    }
  };
  const handleDeleteTodo = (index) => {
    dispatch({ type: "DELETE_TODO", payload: index });
  };
  const handleEditTodo = (index, newTodo) => {
    dispatch({ type: "EDIT_TODO", payload: { index, newTodo } });
    setEditingIndex(-1);
    setEditedTodo("");
  };

Այս կարգավորիչ գործառույթները պատասխանատու են կոնտեքստի վիճակի մեջ օգտագործողի անելիքների ավելացման, ջնջման և խմբագրման համար:

Նրանք ապահովում են, որ երբ օգտատերը ավելացնում է, ջնջում կամ խմբագրում է անելիքները, համապատասխան գործողություններն ուղարկվում են համատեքստի կրճատողին՝ համապատասխանաբար թարմացնելու վիճակը:

Ներկայացրեք անելիքների բաղադրիչը

Վերջապես, ներմուծեք To-do բաղադրիչը էջի բաղադրիչ:

Դա անելու համար բացեք page.js ֆայլը src/app գրացուցակում, ջնջեք boilerplate Next.js կոդը և ավելացրեք ստորև նշված կոդը.

import styles from './page.module.css'
import Todo from '../components/Todo'
export default function Home() {
  return (
    <main className={styles.main}> 
      <Todo /> 
    </main>
  )
}

Հիանալի Այս պահին դուք պետք է կարողանաք կառավարել վիճակը To-do Next.js հավելվածում՝ օգտագործելով React Context:

React Context API-ի օգտագործումը պետական կառավարման այլ տեխնոլոգիաների հետ

React Context API-ն հիանալի լուծում է պետական կառավարման համար: Այնուամենայնիվ, հնարավոր է այն օգտագործել այլ պետական կառավարման գրադարանների հետ, ինչպիսիք են Redux-ը: Այս հիբրիդային մոտեցումը երաշխավորում է, որ դուք օգտագործում եք լավագույն գործիքը ձեր հավելվածի տարբեր մասերի համար, որոնք կատարում են հիմնական դերեր:

Դրանով դուք կարող եք կապիտալացնել տարբեր պետական կառավարման լուծումների առավելությունները՝ արդյունավետ և պահպանվող հավելվածներ ստեղծելու համար: