useContext挂钩从子组件更新

时间:2020-08-22 01:27:39

标签: reactjs react-hooks

我对钩子和useContext还是很陌生,我试图从子组件更新onClick并继续遇到错误“ setPokemonId”不是函数,或者..它只是不执行任何操作完全没有。

PokedexContext.js

import React, { useState, useEffect } from "react";
import axios from "axios";

const PokedexContext = React.createContext([{}, () => {}]);

const PokedexProvider = (props) => {
  const [state, setState] = useState({});
  const [loading, setLoading] = useState(true);
  let [error, setError] = useState(false);
  let [pokemonId, setPokemonId] = useState(10); //807 max

  useEffect(() => {
    setLoading(true);
    setError(false);
    axios
      .get(`https://pokeapi.co/api/v2/pokemon/${pokemonId}`)
      .then((res) => {
        setState(res.data, loading);
        setLoading(false);
      })
      .catch((err) => {
        setLoading(false);
        if (err.response) {
          // pokemon not found
          setError("Response");
        } else if (err.request) {
          // api error
          setError("Request");
        } else {
          // everything else
          setError(true);
        }
      });
  }, [pokemonId]);

  return (
    <PokedexContext.Provider
      value={[
        state,
        setState,
        error,
        loading,
        setLoading,
        pokemonId,
        setPokemonId,
      ]}
    >
      {props.children}
    </PokedexContext.Provider>
  );
};

export { PokedexContext, PokedexProvider };

App.js

import React from "react";
import { PokedexProvider } from "../../context/PokedexContext";
import Pokedex from "../Pokedex";

const Landing = () => {
  return (
    <PokedexProvider>
      <main className="container">
        <Pokedex />
      </main>
    </PokedexProvider>
  );
};

export default Landing;

Pokedex.js

import React, { useState, useContext } from "react";
import pokedex from "../assets/pokedex.png";
import PokedexScreen from "./PokedexScreen";
import errorHandling from "../utils/errorHandling";
import { PokedexContext } from "../context/PokedexContext";
import spinner from "../assets/pika-load.gif";

const Pokedex = () => {
  const [state, setState, error, loading, setPokemonId, pokemonId] = useContext(
    PokedexContext
  );
  const [power, setPower] = useState(false);
  const [shinyDisplay, setShinyDisplay] = useState(false);

  console.log(pokemonId);

  return (
    <div
      alt="Pokedex"
      data-testid="Pokedex"
      className="pokedex"
      style={{ backgroundImage: `url(${pokedex})` }}
    >
      <button className="pokedex--onButton" onClick={() => setPower(!power)}>
        {power ? "Off" : "On"}
      </button>

      {error ? (
        <div className="pokedex--screen__error">{errorHandling(error)}</div>
      ) : power ? (
        <>
          {loading ? (
            <img
              className="pokedex--screen__load"
              src={spinner}
              alt="Loading..."
            />
          ) : (
            ""
          )}

          <button
            className="pokedex--shinyButton"
            onClick={() => setShinyDisplay(!shinyDisplay)}
          >
            S
          </button>
          <span>
            <button
              className="pokedex--negativeButton"
              onClick={() => setPokemonId(pokemonId - 1)}
            >
              -
            </button>
            <button
              className="pokedex--positiveButton"
              //  onClick={}
            >
              +
            </button>
          </span>
  
        </>
      ) : (
        <div className="pokedex--screen__off" />
      )}
    </div>
  );
};

export default Pokedex;

我的目标是在单击肯定或否定按钮时更新pokemonId,这是当前导致崩溃的原因。

1 个答案:

答案 0 :(得分:2)

问题

在Context Provider中导出值时。它在数组的第六个索引中

 <PokedexContext.Provider
      value={[
        state,
        setState,
        error,
        loading,
        setLoading,
        pokemonId,
        setPokemonId, (6)
      ]}
    >
      {props.children}
    </PokedexContext.Provider>

但是您使用的是Pokedex中第4个索引。

  const [state, setState, error, loading, setPokemonId, pokemonId] = useContext(
    PokedexContext
  );

解决方案

const [
        state,
        setState,
        error,
        loading,
        setLoading,
        pokemonId,
        setPokemonId, (6)
      ] = useContext(
    PokedexContext
  );