skip to Main Content

This is initially a JS project from free code camp, but to put it on my portfolio website, I want to make it interactive.

I have tried setting the variables to state and being passed down through props, but the variables will only but initially mutated once, and the display will not update further than that. Here is some of the code that should give an idea of the whole project.

The state for button functions, button text, and text all update and display properly, but the button functions only set the state once and continue to call on the original state.

//JSX file
export default function DragonRepeller() {
const [health, setHealth] = useState({ health: 100 });
const [gold, setGold] = useState({ gold: 50 });
const [text, setText] = useState({ text: 'Welcome to Dragon Repeller. You must defeat the dragon that is preventing people from leaving the town. You are in the town square. Where do you want to go? Use the buttons above.'});
const [buttonText, setButtonText] = useState({ button1: "Go To Store", button2: 'Go to Cave', button3: 'Fight Dragon'});
const button1Text = buttonText.button1
const button2Text = buttonText.button2
const button3Text = buttonText.button3
const [buttonFunction, setButtonFunction] = useState({button1: goStore, button2: goCave, button3: fightDragon});
const button1Function = buttonFunction.button1
const button2Function = buttonFunction.button2
const button3Function = buttonFunction.button3
// various other initializers and some objects 
const locations = [
        {
            name: "town square",
            "button text": ["Go to store", "Go to cave", "Fight dragon"],
            "button functions": [goStore, goCave, fightDragon],
            text: "You are in the town square. You see a sign that says "Store"."
        },
        {
            name: "store",
            "button text": ["Buy 10 health (10 gold)", "Buy weapon (30 gold)", "Go to town square"],
            "button functions": [buyHealth, buyWeapon, goTown],
            text: "You enter the store."
        },
        {/*location[2] commented out for space*/},
        {/*location[3]*/},
        {/*location[4]*/},
        {/*location[5]*/},
        {/*location[6]*/},
        {/*location[7]*/}
    ];
//location functions
    function update(location) {
        setButtonText(() => {
            return {
                button1: location['buttonText'[0]],
                button2: location['buttonText'[1]],
                button3: location['buttonText'[2]]
            }
        });
        setButtonFunction(() => {
            return {
                button1: location['button functions'][0],
                button2: location['button functions'][1],
                button3: location['button functions'][2]
            }
        });
        setText(() => {
            return { text: location.text}
        });
        };
//button functions that use the update(location) function
function goTown() { // starting location
        update(locations[0]);
    };
    function goStore() { // this is the location with the function in question
        update(locations[1]);
    };
    function goCave() {
        update(locations[2]);
    };
//buy health button function, buy weapon works the same 
function buyHealth() {
    if (gold.gold >= 10) {
       setGold((prevGold) => { return { gold: prevGold.gold - 10 }});
       setHealth((prevHealth) => { return { health: prevHealth.health + 10 }});
  } else {
       setText(() => { return { text: 'You do not have enough gold to buy health' }});
  }
 }
//the rest of the code
}
return (
<div id=game>
   <div id='stats'>
      <span className='stat'>Health: <strong><span id='healthText'>{health.health}</span></strong></span>
      <span className='stat'>Gold: <strong><span id='goldText'>{gold.gold}</span></strong></span>
   </div>
   <div id="controls">
       <button id="button1" className='gButton' onClick={button1Function}>{button1Text}</button>
       <button id="button2" className='gButton' onClick={button2Function}>{button2Text}]</button>
       <button id="button3" className='gButton' onClick={button3Function}>{button3Text}</button>
   </div>
   <div id='text'>
      {text.text}
   </div>
</div>
)

I feel like I am going about this the wrong way and could use some help.

I have tried rewriting the code multiple times with varying ways of setting state. Every time I run the code, the text will keep updating can following along with what I have it set to change to, but the other variables only mutate once and then they revert to either the initial state or the first way it changed.

I have tried plain JS instead of JSX and that has run into more issues with the functions not executing.

I have also been scouring stack overflow to find anything that might relate to this but I have not found any solution that works which makes me feel like I am missing a key point here.

2

Answers


  1. setGold((prevGold) => { return: { gold: prevGold.gold - 10 }});
    
    

    syntax error at return :

    change to: for both.

    setGold((prevGold) => { return { gold: prevGold.gold - 10 }});
    
    
    Login or Signup to reply.
  2. When you use arrow function, if the function body contains only a return statement, you can remove the return keyword.
    If the return value is an object, you can wrap it using ( and ).

    These are examples.

    const multiple = (x) => { return 2*x }
    const object = (value) => { return { key: value } }
    

    These are the same as the following:

    const multiple = (x) => 2 * x
    cosnt object = (value) = ({key: value})
    

    So, please use following to avoid potential errors.

    setGold((prevGold) => { return { gold: prevGold.gold - 10 }});
    
    setGold((prevGold) => ({ gold: prevGold.gold - 10 }));
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search