skip to Main Content

Been stuck here for a week and can’t find anything that works.
Here is my context file:

import { createContext, useState, useEffect } from 'react';
import * as sm from './StatManagement';
import { PlayerMenu, BossHpBar, BossArea, MainPage } from './MainPage';
//used for the boss hp bar

interface BossContextValue {
    BossHP: number;
    setBossHP: (value: number) => void;  // Function that takes a number
}

export const BossContext = createContext<BossContextValue>({
    BossHP: sm.boss_stats.hp,
    setBossHP: () => { },
});

function ContextManagement() {

    const [BossHP, setBossHP] = useState(sm.boss_stats.hp);
    useEffect(() => {
        //This never triggers 
        console.log('BossHP updated:', BossHP);
    }, [BossHP]);
    return (
        <BossContext.Provider value={{ BossHP, setBossHP }}>
            <PlayerMenu player='' isPlayerTurn={false} />
            <BossHpBar />
        </BossContext.Provider>
    )
}

export default ContextManagement;

What I’m trying to do is create a global state for BossHP. It should update when this button is clicked:

 export const PlayerMenu: React.FC<PlayerMenuProps> = ({ player, isPlayerTurn }) => {
      const { setBossHP } = useContext(BossContext);
  //other elements
                


                        <div className=' grid grid-cols-2 grid-rows-2'>
                            {current_attacks.map(
                                (attack, index) =>
                                    <li key={index} className='atk-btn'>
                                        <button onClick={() => {
                                            const new_hp = pa.PlayerAttack(attack);

                                            setIsAttackAreaShown(true);
                                            setCurrentAttack(attack);
                                          
                                            setBossHP(new_hp);
                                         }}>

                                       //unrelated
                                    }

Then it should update the progress bar here. This component is only linked to PlayerMenu through the context.

 export const BossHpBar = () => {
    const { BossHP } = useContext(BossContext);
    useEffect(() => {
//doesn't update
    console.log('BossHP updated:', BossHP);
    }, [BossHP]);

    console.log("boss hp bar rendered" + BossHP)
    return (
        <progress className={
            'block h-8 glow-ani-border-black boss-prog w-10/12'
        } value={BossHP} max={sm.boss_stats.max_hp}></progress>
    )
}

2

Answers


  1. You Have to add the file extension name after the file name in import. Like this:

    import { createContext, useState, useEffect } from 'react.js';
    import * as sm from './StatManagement.js';
    import { PlayerMenu, BossHpBar, BossArea, MainPage } from './MainPage.js';
    //used for the boss hp bar
    
    interface BossContextValue {
        BossHP: number;
        setBossHP: (value: number) => void;  // Function that takes a number
    }
    
    export const BossContext = createContext<BossContextValue>({
        BossHP: sm.boss_stats.hp,
        setBossHP: () => { },
    });
    
    function ContextManagement() {
    
        const [BossHP, setBossHP] = useState(sm.boss_stats.hp);
        useEffect(() => {
            //This never triggers 
            console.log('BossHP updated:', BossHP);
        }, [BossHP]);
        return (
            <BossContext.Provider value={{ BossHP, setBossHP }}>
                <PlayerMenu player='' isPlayerTurn={false} />
                <BossHpBar />
            </BossContext.Provider>
        )
    }
    
    export default ContextManagement;
    

    I made as javascript files.
    if it is libraries you can replace it with the lib URL. Or use require if it is from npm.

    Login or Signup to reply.
  2. I created a simple working example based on your code, so when you click the button – the variable in the progress bar is updating.
    You can check an example in playground here

    import React, { createContext, useState, useContext, useEffect } from 'react';
    
    const sm = {
      boss_stats: {
        hp: 100,
        max_hp: 200,
      },
    };
    
    interface PlayerMenuProps {
      player: string;
      isPlayerTurn: boolean;
    }
    
    export const BossContext = createContext<{
      BossHP: number;
      setBossHP: (value: number) => void;
    }>({
      BossHP: sm.boss_stats.hp,
      setBossHP: () => {},
    });
    
    const PlayerMenu: React.FC<PlayerMenuProps> = ({ player, isPlayerTurn }) => {
      const { setBossHP } = useContext(BossContext);
    
      const handleAttack = () => {
        const new_hp = Math.max(0, Math.floor(Math.random() * 100));
        setBossHP(new_hp);
      };
    
      return (
        <div>
          <button onClick={handleAttack}>Attack</button>
        </div>
      );
    };
    
    const BossHpBar = () => {
      const { BossHP } = useContext(BossContext);
    
      return (
        <div>
          <h2>Boss HP: {BossHP}</h2>
          <progress value={BossHP} max={sm.boss_stats.max_hp}></progress>
        </div>
      );
    };
    
    const ContextManagement = () => {
      const [BossHP, setBossHP] = useState(sm.boss_stats.hp);
    
      useEffect(() => {
        console.log('BossHP updated:', BossHP);
      }, [BossHP]);
    
      return (
        <BossContext.Provider value={{ BossHP, setBossHP }}>
          <PlayerMenu player="" isPlayerTurn={false} />
          <BossHpBar />
        </BossContext.Provider>
      );
    };
    
    export default function App() {
      return <ContextManagement />;
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search