reactjs - typescript err: trebuie să existe o metodă '[Symbol.iterator]()' care să returneze un iterator atunci când se folosește hook-ul useReducer în context - de ce?


Folosesc TypeScript, nu sunt prea familiarizat și primesc următoarea eroare atunci când folosesc contextul și hook-ul useReducer - în special pentru metoda mea dispatch primesc asta:

contextProps must have a '[Symbol.iterator]()' method that returns an iterator.

Am încercat să cercetez asta, dar nu reușesc să-mi dau seama ce să fac. Îmi imaginez că e din cauza lui const [state, dispatch]=useContext(GlobalState); și trebuie să specific ceva din cauza array-ului. De asemenea, primesc o eroare ts pentru value in

  <GlobalState.Provider value={[state, dispatch]}>

(vezi în codul de mai jos). Cumva când am un array, toate proprietățile pe care le-am definit în ContextProps lipsesc. Orice ajutor ar fi foarte util!

//context.js file
export interface ProjectProps {
  projects: string[]
}

export interface ContextProps extends ProjectProps {
  show: boolean
  posts: string[]
  //...
}

const initialState = {
  posts: [],
  show: false
  //...
};

export const GlobalState = React.createContext<ContextProps | null>(
  initialState
)

const reducer = (state, action) => {
  switch (action.type) {
    case "SHOW":
      return { ...state, show: !state.show }

    default:
      return state
  }
}

const Store: React.FC<{ children: React.ReactNode }> = ({children}) => {
  const [state, dispatch] = useReducer(Reducer, initialState);
  return (
      <GlobalState.Provider value={[state, dispatch]}>
          {children}
      </GlobalState.Provider>
  )
};


const App = () => {
  return (
      <Store>
          <Header/>
          <Blog/>
      </Store>
  );
};

const Blog = () => {

  const [state, dispatch] = useContext(GlobalState);

  return (
      <div>
        <button onClick={dispatch({type: "SHOW"})}></button>
        {state.show ? <p>hello</p> : null }
      </div>
  );
};

Răspuns #1

Se pare că există câteva lucruri greșite în codul pe care l-ați furnizat.

În primul rând, aș începe prin a adăuga mai multe tipizări.
În special pentru parametrii și rezultatul funcției reducer și pentru const [state, dispatch]=useReducer(reducer, initialState); (notă: presupun că reducer era menit să fie cu literă mică aici, deși în exemplul tău de cod este Reducer.

În continuare, cred că există o problemă cu definiția contextului tău comparativ cu modul în care îl folosești.
Dacă vrei să furnizezi atât state, cât și dispatch către Provider-ul tău (așa cum este indicat de <GlobalState.Provider value={[state, dispatch]}>), atunci aș aștepta ca definiția contextului tău să arate mai mult așa:

interface Context {
  state: {
    show: boolean;
    posts: string[];
    //...
  };
  dispatch: React.Dispatch<any>; // I don't know what any should be in your case
}

Rețineți că:

  • Furnizorul tău s-ar schimba în: <GlobalState.Provider value={{state, dispatch}}>.
  • Utilizarea s-ar schimba în: const {state, dispatch}=useContext(GlobalState);

Dacă chiar vrei să folosești [state, dispatch] ca rezultat al contextului tău, atunci ar trebui să folosești un tip precum type Context=[{show: boolean; posts: string[];}, React.Dispatch<any>] în loc de un interface.

În cele din urmă, o eroare precum ... trebuie să aibă o metodă '[Symbol.iterator]()' care să returneze un iterator. de obicei înseamnă că iterați (folosind for, while, ...) printr-un obiect care nu este un tip care poate fi iterat. Un exemplu de tip care poate fi iterat ar fi un Array.
Dacă doriți mai multe indicații despre această ultimă eroare, atunci ar fi util să specificați exact unde apare această eroare.