2

I have a state named rounds and prop current_round. Default value for current_round is 0. What I want to do with these value is that listing buttons with integer. For example, if value of rounds is 4, listing buttons of 1, 2, 3 and 4.

for (var i =(this.props.order.order.current_round + 1); i<(this.props.order.rounds+1); i++) {

  return (
    <li><button id ={i} class="rounds_btn">{i}</button></li>
    );
  }

So to do that, I made for loop like above, but it only shows one button of integer 1..

What is wrong with my code? it doesn't show any errors.

Thanks in advance

3 Answers 3

7

If you return inside a loop, then the entire function (including the loop) is going to finish executing.

The way to solve this problem is to create an array of components then return the entire array after the loop.

let { rounds, current_round } = this.props.order;
let list = [];

for (let i = current_round + 1; i < rounds + 1; i++) {
  list.push(
    <li>
      <button id={i} key={i} className="rounds_btn">{i}</button>
    </li>
  );
}

return list;

However, the usual way to do this with React is to use the map function.

let { order } = this.props;
let nums = range(order.current_round + 1, order.rounds + 1);

return nums.map(i => (
  <li><button key={i} id={i} className='rounds_btn'></button></li>
));

// quick range utility (could use lodash...)
function range(start, end) {
  let nums = [];
  for (let i = start; i < end; i++) nums.push(i);
  return nums;
}

In most cases you'll already have your array (list of people, list of items, etc) and all you need to do is map each one to a React component, then return that list.

I've also added a key attribute, which React will warn you about, if you forget it for lists of components (helps with reconciling the list if you re-render it in a different order).

Also watch out for using class rather than className, because class is a reserved word in JavaScript, React chooses to use className as the JSX prop instead.

Sign up to request clarification or add additional context in comments.

Comments

3

I guess it's just return the first value in the render function. you should put the results in a variable and then render this variable.

const buttons = [];

for (var i =(this.props.order.order.current_round + 1); i<(this.props.order.rounds+1); i++) {

  buttons.push(
    <li><button id ={i} class="rounds_btn">{i}</button></li>
  );
}

return (<ul> {buttons} </ul>);

Comments

0

My answer would be as below in TS

  const Buttons= (numOfButtons : number) => {
    return (
      <>
        {Array.from(Array(numOfButtons)).map((s, i) => (
         <li><button key={i} id={i} className='rounds_btn'></button></li>
        ))}
      </>
    );
  };

Then use the sub-components <Buttons numOfButtons={3}/> anywhere you like

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.