-1

I am trying to render a child component only if a condition is met but no matter what I try, nothing really works. I get all sort of errors.

My application is a store than contains a list of fruits available to clients. I want to render only the items selected into their basket. That's what Facture.js is trying to do. I'm trying to check the count of every fruits in the list that has count > 0 and nothing when it's 0.

Right now, it's rendering everything in the list, even though I do not want them – I know in this actual code there is no condition, so it returns everything.

Shouldn't it just be as simple as an if block?


Here is my full code structure if it helps :

App.js

import Client from "./Client";

state = { fruits : [{name: "Apple", price: "3", count: 2}, 
                    {name: "Orange", price: "2", count: 0}] }

render() { <Client fruits={this.state.fruits}/> }

// I tried this : {this.props.fruits.count > 0 ? <Factures fruits={this.props.fruits} /> : null} but it returns nothing.

Client.js

import Factures from "./Factures";
render() { <Factures fruits={this.props.fruits}/> }

Factures.js

import Facture from "./Facture";
render() {
      return this.props.fruits.map(fruit => <Facture key={fruit.nom} fruit={fruit} /> );
}

Facture.js

class Facture extends React.Component {
   render() {
      return (
         <li className='list-group-item d-flex justify-content-between small'>
            <div className=''>{this.props.fruit.name}</div>
            <div className=''>{'x' + this.props.fruit.count}</div>
         </li>
      );
   }
}

export default Facture;
pensum
  • 980
  • 1
  • 11
  • 25
  • I think you need to add more detail. For instance, you talk about a list but I don't see one. What do you want to render if `count <= 0`, nothing? – Christian Fritz Jan 18 '20 at 03:04
  • 2
    You could do like Luke answer's says, and just return `false` or `null` from a render to render nothing. But a better idea is to control whether it's rendered at all from the parent. So in the parent that's rendering this list of fruits, when rendering filter out any with a count of 0. I think it's more React-y for a parent to control the rendering of its children, than them controlling the rendering of themselves. – Jayce444 Jan 18 '20 at 03:30
  • I will try that, but Luke's solution is not working. I am getting an error in my IDE which breaks my code. It was one of my attempts and I gave up trying. I commented on his answer a screenshot of the attempt. – pensum Jan 18 '20 at 03:38
  • Does this answer your question? [if-else statement inside jsx: ReactJS](https://stackoverflow.com/questions/44046037/if-else-statement-inside-jsx-reactjs) – Emile Bergeron Jan 18 '20 at 04:21
  • @EmileBergeron I can't really apply this with my structure. I don't see how I could. I have edited my post so that you can see what I'm trying to achieve. – pensum Jan 18 '20 at 04:34
  • 1
    The other way is to not even get to `Facture` by filtering first: ` f.count)}/>`. React is data-driven. Data goes from top of the tree to the bottom component, transform the data as needed before passing it to the next component. – Emile Bergeron Jan 18 '20 at 04:45
  • @EmileBergeron Thanks. Filtering before sending down the data is much more easier. You can post as an answer because it fixed it. – pensum Jan 18 '20 at 04:51
  • You are missing a few `return` statements in your `render` functions – kennyvh Jan 18 '20 at 10:40

2 Answers2

1

You can do it a couple of ways:

Option A: Filter the array of fruits before passing it in as props to Client

This method means you won't need a condition in your children components because you'll only be passing fruits that you want to be rendered as props.

// only keep fruits if fruit.count > 0
render() { <Client fruits={this.state.fruits.filter(fruit => fruit.count > 0}/> }

Option B: Conditional rendering in the Facture component

This method will check every fruit's count and only render the fruits where fruit.count > 0.

class Facture extends React.Component {
  render() {
    // if `fruit.count > 0`, render. otherwise, null
    return this.props.fruit.count > 0 ? (
      <li className="list-group-item d-flex justify-content-between small">
        <div className="">{this.props.fruit.name}</div>
        <div className="">{"x" + this.props.fruit.count}</div>
      </li>
    ) : null;
  }
}

export default Facture;
kennyvh
  • 2,526
  • 1
  • 17
  • 26
0
class Facture extends React.Component {
   constructor(props) {
     super(props);
   }

   render() {
      return (
        {this.props.fruit.count > 0 && 
         <li className='list-group-item d-flex justify-content-between small'>
            <div className=''>{this.props.fruit.name}</div>
            <div className=''>{'x' + this.props.fruit.count}</div>
         </li>
        }
      );
   }
}

export default Facture;
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Luke
  • 1,736
  • 2
  • 16
  • 34
  • It is not working. I get this : https://i.imgur.com/I07zx2C.png – pensum Jan 18 '20 at 03:39
  • add this right above the word render constructor(props) { super(props); } – Luke Jan 18 '20 at 04:00
  • Now it's telling me that `:` is expected.. But now that I comment the constructor part I still get the `:` error instead of the original one in the screenshot. It really looks like the code isn't compiling more than a variable is missing or something. – pensum Jan 18 '20 at 04:04
  • take away the ( after the && like above and the ) before the } after the closing li – Luke Jan 18 '20 at 04:07
  • It changes nothing. That was my attempt before I posted on here. I'll post a full structure of my code so that it may help to better picture it? – pensum Jan 18 '20 at 04:08