137

I need to change render function and run some sub render function when a specific state given,

For example:

render() {
    return (   
        <View style={styles.container}>
            if (this.state == 'news'){
                return (
                    <Text>data</Text>
                )
            }
        </View>
    )
}

How can I implement that without changing scenes, I will use tabs to change content dynamically.

Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
user8026867
  • 1,849
  • 3
  • 11
  • 11

17 Answers17

230

As per DOC:

if-else statements don't work inside JSX. This is because JSX is just syntactic sugar for function calls and object construction.

Basic Rule:

JSX is fundamentally syntactic sugar. After compilation, JSX expressions become regular JavaScript function calls and evaluate to JavaScript objects. We can embed any JavaScript expression in JSX by wrapping it in curly braces.

But only expressions not statements, means directly we can not put any statement (if-else/switch/for) inside JSX.


If you want to render the element conditionally then use ternary operator, like this:

render() {
    return (   
        <View style={styles.container}>
            {this.state.value == 'news'? <Text>data</Text>: null }
        </View>
    )
}

Another option is, call a function from jsx and put all the if-else logic inside that, like this:

renderElement(){
   if(this.state.value == 'news')
      return <Text>data</Text>;
   return null;
}

render() {
    return (   
        <View style={styles.container}>
            { this.renderElement() }
        </View>
    )
}
Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
  • can I do like that? render() { return ( if (this.state == 'news'){ return ( data ) } – user8026867 May 18 '17 at 11:15
  • so return inside return is possible? or two different returns in same render function scene I need to change sub content of return – user8026867 May 18 '17 at 11:15
  • yes that is possible but, in a different way directly we can't use if/else inside JSX so use ternary operator for conditions, use this: `render() { return ( {this.state == 'news' ? data : null } ) }` – Mayank Shukla May 18 '17 at 11:17
  • ` { if (this.state.page == 'sohbet'){ } ` not possible? } – user8026867 May 18 '17 at 11:30
  • that is well explained in doc, check this for reason: http://reactjs.cn/react/tips/if-else-in-JSX.html – Mayank Shukla May 18 '17 at 11:34
  • 404 but how can I call a function rather than a text in here this.state.page == 'sohbet' ? data :null – user8026867 May 18 '17 at 11:40
  • it was working don't know what's the issue,reason is: The content of {...} must be an expression, if-else/for/switch are statements. yes you can do one thing you can call a function and put the if/else inside that, will update the answer :) – Mayank Shukla May 18 '17 at 11:44
  • ..return {res.text()}... that function returns this but it show nothing is that wrong I nee to return jsx code from this function – user8026867 May 18 '17 at 11:51
  • what is `res.text()` ? if `test` is a name of function then you need to call that by using `this.text()`, not by res can you show the full code it will be easy to help you, check the updated answer how to call the function. – Mayank Shukla May 18 '17 at 11:54
  • its just text //alert(res.text()); works but not returning anything to text inside – user8026867 May 18 '17 at 11:57
  • pulldata() { return aaa // send http request in a new thread (using native code) RNFetchBlob.fetch('GET', 'http://bigpaaasasas', { // Authorization : 'Bearer access-token...', // more headers .. }) // when response status code is 200 .then((res) => { // the conversion is done in native code // let base64Str = res.base64() //alert(res.text()); // this.state = {page: res.text()}; return aaa – user8026867 May 18 '17 at 12:02
  • its a asyn call it will not return the updated div directly, you need to use the state variable, like this: `pulldata() { RNFetchBlob.fetch('GET', 'bigpaaasasas';, { Authorization : 'Bearer access-token...', }) .then((res) => { let base64Str = res.base64() this.setState({page: res.text()}); }) } render() { return ( {this.state.page == 'news' ? : this.state.page : 'aaa' ) }` – Mayank Shukla May 18 '17 at 13:08
  • set the data in state variable and once you do setState it will update the ui, and check the condition inside render method. – Mayank Shukla May 18 '17 at 13:09
  • Great, https://react-cn.github.io/react/tips/if-else-in-JSX.html this helps me – Nadeesha Nawagaththegama Nov 10 '22 at 08:12
64

You can achieve what you are saying by using Immediately Invoked Function Expression (IIFE)

render() {
    return (   
        <View style={styles.container}>
            {(() => {
              if (this.state == 'news'){
                  return (
                      <Text>data</Text>
                  )
              }
              
              return null;
            })()}
        </View>
    )
}

Here is the working example:

Edit awesome-yalow-eb2nu

But, In your case, you can stick with the ternary operator

Yusufbek
  • 2,180
  • 1
  • 17
  • 23
  • @Yusufbek can you help me why in this part " if (this.state == 'news'){ return (
    data1 data2 ) }" doesnt work
    – Aakash Mathur Apr 16 '21 at 18:08
  • meaning in the above return we use div for mutliple elemnts 2 text – Aakash Mathur Apr 16 '21 at 18:09
  • @AakashMathur it should work. Make sure you are returning only 1 root element and you have else statement to return null – Yusufbek Apr 16 '21 at 19:31
  • 2
    You can achieve a much more intuitive solution by switching to Vue. It boggles my mind that such a hack has to be done for something so fundamental. – GHOST-34 Oct 29 '21 at 22:18
39

I find this way is the nicest:

{this.state.yourVariable === 'news' && <Text>{data}<Text/>}
MMachinegun
  • 3,044
  • 2
  • 27
  • 44
sooper
  • 5,991
  • 6
  • 40
  • 65
  • 4
    I agree, this is the nicest of the bunch. Returning `null` with a ternary-operator is unnecessary ;) – MMachinegun Oct 23 '17 at 16:22
  • This should be added to the main answer. – Fatih Aktaş Jan 14 '19 at 22:36
  • How could I use this in my case? If I use it like this ```{localStorage.getItem('token') && Invalid Login}```it will be rendered even before the form is submitted. https://stackoverflow.com/questions/60577971/conditional-rendering-inside-a-function –  Mar 07 '20 at 13:35
  • This helped me in my case, however, I had to wrap elements in <>...>. – Strabek Jun 20 '20 at 09:04
  • This works well if you do not need a false-case outcome which the ternary syntax can provide. – Ozone Feb 20 '23 at 16:59
14

I do like this and its working fine.

constructor() {
   super();

   this.state ={
     status:true
   }
}

render() {
   return( 

     { this.state.status === true ?
           <TouchableHighlight onPress={()=>this.hideView()}>
             <View style={styles.optionView}>
               <Text>Ok Fine :)</Text>
             </View>
          </TouchableHighlight>
           :
           <Text>Ok Fine.</Text>
     }
  );
}

hideView(){
  this.setState({
    home:!this.state.status
  });
}
Manish Ahire
  • 1,243
  • 13
  • 11
  • 1
    @Pierre.Vriens Instead of if-else, you can use ternary operators in render() method. Syntax :- condition ? expr1 : expr2 Ex. if (this.state.status === true) { } else { } – Manish Ahire Aug 21 '18 at 08:12
3

You can do this. Just don't forget to put "return" before your JSX component.

Example:

render() {
    if(this.state.page === 'news') {
        return <Text>This is news page</Text>;
    } else {
        return <Text>This is another page</Text>;
    }
}

Example to fetch data from internet:

import React, { Component } from 'react';
import {
    View,
    Text
} from 'react-native';

export default class Test extends Component {
    constructor(props) {
        super(props);

        this.state = {
            bodyText: ''
        }
    }

    fetchData() {
        fetch('https://example.com').then((resp) => {
            this.setState({
                bodyText: resp._bodyText
            });
        });
    }

    componentDidMount() {
        this.fetchData();
    }

    render() {
        return <View style={{ flex: 1 }}>
            <Text>{this.state.bodyText}</Text>
        </View>
    }
}
Jagjot
  • 5,816
  • 2
  • 24
  • 41
  • can you show me a little full working example sorry I am new to this – user8026867 May 18 '17 at 11:09
  • @user8026867 example added – Jagjot May 18 '17 at 11:42
  • i want to return from inside a function – user8026867 May 18 '17 at 12:18
  • @user8026867 you can make a function and return the JSX component there. Try it and see if you can make it otherwise I'll give you an example. – Jagjot May 18 '17 at 12:35
  • alert works ok but not rendering happens after .then how can I do that pulldata() { RNFetchBlob.fetch('GET', 'http://bigcom', { }) .then((res) => { alert(res.text()); return {res.text()} }) .catch((errorMessage, statusCode) => { alert(errorMessage); }) } – user8026867 May 18 '17 at 12:36
  • @user8026867 You shouldn't fetch data like this. I've added an example on how to fetch data from the internet and show it in your render method. You should use states wherever you want your data to be dynamic. And moreover do not call functions in the render method as render method keeps re-rendering multiple times, which may result in calling the same function multiple times unnecessarily. I hope this helps – Jagjot May 18 '17 at 17:07
  • { this.state.page == 'haberler' ? this.pulldata(); return {this.state.bodyTexts} :null } – user8026867 May 18 '17 at 17:43
3

There's a Babel plugin that allows you to write conditional statements inside JSX without needing to escape them with JavaScript or write a wrapper class. It's called JSX Control Statements:

<View style={styles.container}>
  <If condition={ this.state == 'news' }>
    <Text>data</Text>
  </If>
</View>

It takes a bit of setting up depending on your Babel configuration, but you don't have to import anything and it has all the advantages of conditional rendering without leaving JSX which leaves your code looking very clean.

Chase Sandmann
  • 4,795
  • 3
  • 30
  • 42
2

What about switch case instead of if-else

  render() {
    switch (this.state.route) {
      case 'loginRoute':
        return (
            <Login changeRoute={this.changeRoute}
              changeName={this.changeName}
              changeRole={this.changeRole} />
        );
      case 'adminRoute':
        return (
            <DashboardAdmin
              role={this.state.role}
              name={this.state.name}
              changeRoute={this.changeRoute}
            />
        );
      default: 
        return <></>;
    }
Viraj Singh
  • 1,951
  • 1
  • 17
  • 27
2
 <Card style={
  { backgroundColor: '#ffffff', 
    height: 150, width: 250, paddingTop: 10 }}>
                                
<Text style={styles.title}> 
 {item.lastName}, {item.firstName} ({item.title})
</Text> 
<Text > Email: {item.email}</Text>
 {item.lastLoginTime != null ? 
   <Text >  Last Login: {item.lastLoginTime}</Text> 
   : <Text >  Last Login: None</Text>
 }
 {
   item.lastLoginTime != null ? <Text >  
   Status: Active</Text> : <Text > Status: Inactive</Text>
 }                              
</Card>
Juan Antonio
  • 2,451
  • 3
  • 24
  • 34
spoorthi vaidya
  • 411
  • 5
  • 9
2

There is no need for the if else condition in JSX. It provides a function like ternary operator to make the thing happen for you, example:

state={loading:false}
<View>
  {loading ? <Text>This is a test For if else condition</Text> : <ActivityIndicator/>
</View>
DᴀʀᴛʜVᴀᴅᴇʀ
  • 7,681
  • 17
  • 73
  • 127
2

If you want to use an conditional statement in functional component then you can call a function from jsx and put all your conditional logic inside it.

conditionalRender(){
   if(state === 'news') {
      return <Text>data</Text>;
   }
   else(state !== 'news') {
      return <Text>Static Value</Text>;
   }
}

render() {
    return (   
        <View style={styles.container}>
            { conditionalRender() }
        </View>
    )
}
1
 render() {
     return (   
         <View style={styles.container}>
         (() => {                                                       
             if (this.state == 'news') {
                return  <Text>data</Text>
            }
            else 
             return  <Text></Text>
        })()
         </View>
     )
 }

https://react-cn.github.io/react/tips/if-else-in-JSX.html

user193679
  • 181
  • 2
  • 6
1

Simple example of nested loop with if condition in React:

Data example:

    menus: [
    {id:1, name:"parent1", pid: 0},
    {id:2, name:"parent2", pid: 0},
    {id:3, name:"parent3", pid: 0},
    {id:4, name:"parent4", pid: 0},
    {id:5, name:"parent5", pid: 0},
    {id:6, name:"child of parent 1", pid: 1},
    {id:7, name:"child of parent 2", pid: 2},
    {id:8, name:"child of parent 2", pid: 2},
    {id:9, name:"child of parent 1", pid: 1},
    {id:10, name:"Grand child of parent 2", pid: 7},
    {id:11, name:"Grand child of parent 2", pid: 7},
    {id:12, name:"Grand child of parent 2", pid: 8},
    {id:13, name:"Grand child of parent 2", pid: 8},
    {id:14, name:"Grand child of parent 2", pid: 8},
    {id:15, name:"Grand Child of Parent 1 ", pid: 9},
    {id:15, name:"Child of Parent 4 ", pid: 4},
    ]

Nested Loop and Condition:

    render() {
    let subMenu='';
    let ssubmenu='';
    const newMenu = this.state.menus.map((menu)=>{
    if (menu.pid === 0){
    return (
    <ul key={menu.id}>
       <li>
          {menu.name}
          <ul>
             {subMenu = this.state.menus.map((smenu) => {
             if (menu.id === smenu.pid) 
             {
             return (
             <li>
                {smenu.name}
                <ul>
                   {ssubmenu = this.state.menus.map((ssmenu)=>{
                   if(smenu.id === ssmenu.pid)
                   {
                   return(
                   <li>
                      {ssmenu.name}
                   </li>
                   )
                   }
                   })
                   }
                </ul>
             </li>
             )
             }
             })}
          </ul>
       </li>
    </ul>
    )
    }
    })
    return (
    <div>
       {newMenu}
    </div>
    );
    }
    }
ForeverZer0
  • 2,379
  • 1
  • 24
  • 32
0

You can't provide if-else condition in the return block, make use of ternary block, also this.state will be an object, you shouldn't be comparing it with a value, see which state value you want to check, also return returns only one element, make sure to wrap them in a View

render() {
    return (
      <View style={styles.container}>
      {this.state.page === 'news'? <Text>data</Text>: null}
      </View>

     )
}
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
0

In two ways we can solve this problem:

  1. Write a else condition by adding just empty <div> element.
  2. or else return null.
render() {
    return (   
        <View style={styles.container}>
            if (this.state == 'news'){
                return (
                    <Text>data</Text>
                );
            }
            else {
                 <div> </div>
            }

        </View>
    )
}
0

Just Tried that:

return(
  <>
    {
      main-condition-1 && 
      main-condition-2 &&
      (sub-condition ? (<p>Hi</p>) : (<p>Hello</p>))
     }
  </>
)

Let me know what you guys think!!!

Adarsh Pawar
  • 682
  • 6
  • 15
0

Just Write Down The Code

 <> 
    {row.photo != null ? <img src={serverPath(row.photo)} className='img-fluid shadow-4' alt="" /> : ''}
 </>

-1

For this we can use ternary operator or if there is only one condition then "&&" operator .Like this:-

//This is for if else

render() {

return (   
    <View style={styles.container}>
      {this.state == 'news') ?
           <Text>data</Text>
        : null}
    </View>
)

}

//This is only for if or only for one condition

render() {

return (   
    <View style={styles.container}>
      {this.state == 'news') &&
           <Text>data</Text>
        }
    </View>
)

}

Si8
  • 9,141
  • 22
  • 109
  • 221
sneha
  • 435
  • 4
  • 9