Devon F
Devon F

Reputation: 73

Variable being passed as a property not rendering in react

New to react and I'm assuming this will be an easy question for someone but I can't find a specific question that answers this issue. I did a react tutorial and afterwards I decided to test myself by adding a few more functional buttons to the webpage. First, the webpage looks like this : enter image description here

What I want to do is display the total count of all of the counters (the array can vary in size etc) next to the total count. Currently I am doing that like this: First, my navbar component :

const NavBar = ({ totalCounters }, { totalCount }) => {
  return (
    <nav className="navbar navbar-light bg-light">
      <a className="navbar-brand" href="www.thisisirellevant.com">
        Navbar{" "}
        <span className="badge badge-pill badge-secondary">
          # of Nonzero Counters: {totalCounters}
        </span>
        <span className="badge badge-pill badge-secondary m-2">
          Total Count: {totalCount}
        </span>
      </a>
    </nav>
  );
};

And now how I am rendering this in the parent:

const sum = this.sumValues();
    return (
      <React.Fragment>
        <NavBar
          totalCounters={this.state.counters.filter((c) => c.value > 0).length} //this is a little different becuase we made it a functional component (it only raises events)
          totalCount={sum}
        />

(Not showing the entire fragment, the fragment does close eventually) And finally the sum function I created in the App class:

sumValues() {
    var sum = 0;
    var counter;
    for (counter in this.state.counters) {
      sum += counter["value"];
    }
    return sum;
  }

Could anyone tell me why the Total Count is not being displayed? I feel like I am passing everything around correctly and returning an integer from the sum function, but as you can see from the image above nothing is ever rendered in its place. Any tips would be appreciated, sorry for such a novice question. Thanks all!

Upvotes: 2

Views: 976

Answers (1)

J&#243;zef Podlecki
J&#243;zef Podlecki

Reputation: 11283

Apart from obvious ({ totalCounters }, { totalCount }) mistake in NavBar component I would suggest using for of loop when computing sum.

Example

const { Component, useState, useEffect } = React;

const NavBar = ({ totalCounters, totalCount, isComputing }) => {
  return <div>
    <div>Counters: {totalCounters}</div>
    {isComputing ? <div>Computing count...</div> : <div>Count: {totalCount}</div>}
  </div>
}
 
class App extends Component {
  constructor(props) {
    super(props);
    this.sumValues = this.sumValues.bind(this);
    
    this.state = {
      count: -1,
      isComputing: true,
      counters: Array(Math.floor(Math.random() * 10)).fill(0).map((pr, index) => ({value: index}))
    }
    this.mounted = false;
  }
  
  componentDidMount() {
    this.mounted = true;
    setTimeout(() => {
      
      const count = this.sumValues();
      const isComputing = false;
      if(this.mounted) {
        this.setState(state => ({...state, count, isComputing}))
      }
    }, 300);
  }
  
  componentWillUnmount() {
    this.mounted = false;
  }
  
  sumValues() {
    let sum = 0;
    const { counters } = this.state;
    
    for (let { value } of counters) {
      sum += value;
    }
    return sum;
  }

  render() {
    const { counters, count, isComputing } = this.state;
  
    return <div>
       <NavBar
            totalCounters={counters.filter((c) => c.value > 0).length}
            totalCount={count}
            isComputing={isComputing}
          />
    </div>
  }
}

ReactDOM.render(
    <App />,
    document.getElementById('root')
  );
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<div id="root"></div>

Ideally you would add another state count which can store your calculation.

Upvotes: 1

Related Questions