【问题标题】:useContext hook update from child componentuseContext 钩子从子组件更新
【发布时间】:2020-08-22 01:27:39
【问题描述】:

我对 hooks 和 useContext 还很陌生,我正在尝试从子组件更新 onClick 并不断遇到错误 'setPokemonId' is not a function,或者.. 它什么也没做完全没有。

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,这是当前导致崩溃的原因。

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    问题

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

     <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
      );
    

    【讨论】:

    • 啊,非常感谢!还通过将提供者更改为对象而不是数组来进一步解决它。
    猜你喜欢
    • 2019-06-21
    • 1970-01-01
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 2019-07-08
    相关资源
    最近更新 更多