javascript - How to handle promises inside the JSX in React JS? - Stack Overflow

This is the first time I came across handling the promises inside the JSX in my React JS project.Here i

This is the first time I came across handling the promises inside the JSX in my React JS project.

Here is my ponent code.

import React from 'react';
import Sodexo from './Sodexo';
import { connect } from 'react-redux';
import {withCookies} from 'react-cookie';

import ticketImg from './../../images/web-images/ticketrest.png';
import sodexImg from './../../images/web-images/sodexo.png';

import {selectMealVoucher} from './../../actions/paymentActions';
import {getSavedCard} from './../../utils/PaymentGateway';


class MealVoucher extends React.Component {

    checkCardSaved = async () => {
        const {cookies} = this.props.cookies;
        const card = await getSavedCard(cookies.id,cookies.token);
        const {sodexo} = card.data;

        return sodexo.length === 0 ? 0 : 1;
    }

    render() {
        const {sodexo, ticketrestaurant} = this.props;
        return (
            <div>
                <div class="row">
                    <div className="col-md-1 col-sm-1"></div>
                    <div class="col-md-5 col-sm-5">
                        <div class="form-group">
                            <input 
                                type="radio" 
                                name="mealvoucher"
                                {...sodexo.isActive ? {checked: true} : {}} 
                                onChange={() => this.props.selectMealVoucher('sodexo')}
                            />
                            <img src={sodexImg} height="30px" style={{marginLeft:'15px'}}/>
                        </div>
                    </div>

                    <div class="col-md-5 col-sm-5">
                        <div class="form-group">
                            <input 
                                type="radio" 
                                name="mealvoucher"
                                {...ticketrestaurant ? {checked: true} : {}} 
                                onChange={() => this.props.selectMealVoucher('ticketrestaurant')}
                            />
                            <img src={ticketImg} height="30px" style={{marginLeft:'15px'}} />
                        </div>
                    </div>
                </div>

                {
                    sodexo.isActive ? (
                       this.checkCardSaved().then(res => {
                           res ? <Sodexo /> : ''
                       })
                    ): ''
                }

            </div>
        );
    }
}

const mapStateToProps = state => state.paymentpage.paymentoption.mealvouchers;
const mapDispatchToProps = {selectMealVoucher};

export default withCookies(connect(mapStateToProps,mapDispatchToProps)(MealVoucher));

In the above, I am trying to call checkSavedCard() inside the JSX, but even if I am returning the 0 or 1 from checkSavedCard(), I see that promise is getting returned instead of 0 or 1.

So I used .then() and tried to render another ponent depending on the value returned by the checkSavedCard().

But, this isn't working and instead, I am getting an error message.

Objects are not valid as a React child (found: [object Promise]).

So, I came up with a different approach. I created one global variable and inside the checkSavedCard() instead of returning the value I am saving that value to the global variable and then inside the JSX I am checking for the value of that global variable.

This approach works fine for me.

Here is the working ponent code.

import React from 'react';
import Sodexo from './Sodexo';
import { connect } from 'react-redux';
import {withCookies} from 'react-cookie';

import ticketImg from './../../images/web-images/ticketrest.png';
import sodexImg from './../../images/web-images/sodexo.png';

import {selectMealVoucher} from './../../actions/paymentActions';
import {getSavedCard} from './../../utils/PaymentGateway';


class MealVoucher extends React.Component {
    cardStatus;

    ponentDidMount() {
        this.checkCardSaved();
    }

    checkCardSaved = async () => {
        const {cookies} = this.props.cookies;
        const card = await getSavedCard(cookies.id,cookies.token);
        const {sodexo} = card.data;

        this.cardStatus = sodexo.length === 0 ? 0 : 1;
    }

    render() {
        const {sodexo, ticketrestaurant} = this.props;
        return (
            <div>
                <div class="row">
                    <div className="col-md-1 col-sm-1"></div>
                    <div class="col-md-5 col-sm-5">
                        <div class="form-group">
                            <input 
                                type="radio" 
                                name="mealvoucher"
                                {...sodexo.isActive ? {checked: true} : {}} 
                                onChange={() => this.props.selectMealVoucher('sodexo')}
                            />
                            <img src={sodexImg} height="30px" style={{marginLeft:'15px'}}/>
                        </div>
                    </div>

                    <div class="col-md-5 col-sm-5">
                        <div class="form-group">
                            <input 
                                type="radio" 
                                name="mealvoucher"
                                {...ticketrestaurant ? {checked: true} : {}} 
                                onChange={() => this.props.selectMealVoucher('ticketrestaurant')}
                            />
                            <img src={ticketImg} height="30px" style={{marginLeft:'15px'}} />
                        </div>
                    </div>
                </div>

                {
                    sodexo.isActive && this.cardStatus ? (
                       <Sodexo />
                    ): ''
                }

            </div>
        );
    }
}

const mapStateToProps = state => state.paymentpage.paymentoption.mealvouchers;
const mapDispatchToProps = {selectMealVoucher};

export default withCookies(connect(mapStateToProps,mapDispatchToProps)(MealVoucher));

But I think this isn't a perfect solution, there might be something provided by React JS, to handle the promises inside the JSX.

I googled it but I didn't find any solution on this.

This is the first time I came across handling the promises inside the JSX in my React JS project.

Here is my ponent code.

import React from 'react';
import Sodexo from './Sodexo';
import { connect } from 'react-redux';
import {withCookies} from 'react-cookie';

import ticketImg from './../../images/web-images/ticketrest.png';
import sodexImg from './../../images/web-images/sodexo.png';

import {selectMealVoucher} from './../../actions/paymentActions';
import {getSavedCard} from './../../utils/PaymentGateway';


class MealVoucher extends React.Component {

    checkCardSaved = async () => {
        const {cookies} = this.props.cookies;
        const card = await getSavedCard(cookies.id,cookies.token);
        const {sodexo} = card.data;

        return sodexo.length === 0 ? 0 : 1;
    }

    render() {
        const {sodexo, ticketrestaurant} = this.props;
        return (
            <div>
                <div class="row">
                    <div className="col-md-1 col-sm-1"></div>
                    <div class="col-md-5 col-sm-5">
                        <div class="form-group">
                            <input 
                                type="radio" 
                                name="mealvoucher"
                                {...sodexo.isActive ? {checked: true} : {}} 
                                onChange={() => this.props.selectMealVoucher('sodexo')}
                            />
                            <img src={sodexImg} height="30px" style={{marginLeft:'15px'}}/>
                        </div>
                    </div>

                    <div class="col-md-5 col-sm-5">
                        <div class="form-group">
                            <input 
                                type="radio" 
                                name="mealvoucher"
                                {...ticketrestaurant ? {checked: true} : {}} 
                                onChange={() => this.props.selectMealVoucher('ticketrestaurant')}
                            />
                            <img src={ticketImg} height="30px" style={{marginLeft:'15px'}} />
                        </div>
                    </div>
                </div>

                {
                    sodexo.isActive ? (
                       this.checkCardSaved().then(res => {
                           res ? <Sodexo /> : ''
                       })
                    ): ''
                }

            </div>
        );
    }
}

const mapStateToProps = state => state.paymentpage.paymentoption.mealvouchers;
const mapDispatchToProps = {selectMealVoucher};

export default withCookies(connect(mapStateToProps,mapDispatchToProps)(MealVoucher));

In the above, I am trying to call checkSavedCard() inside the JSX, but even if I am returning the 0 or 1 from checkSavedCard(), I see that promise is getting returned instead of 0 or 1.

So I used .then() and tried to render another ponent depending on the value returned by the checkSavedCard().

But, this isn't working and instead, I am getting an error message.

Objects are not valid as a React child (found: [object Promise]).

So, I came up with a different approach. I created one global variable and inside the checkSavedCard() instead of returning the value I am saving that value to the global variable and then inside the JSX I am checking for the value of that global variable.

This approach works fine for me.

Here is the working ponent code.

import React from 'react';
import Sodexo from './Sodexo';
import { connect } from 'react-redux';
import {withCookies} from 'react-cookie';

import ticketImg from './../../images/web-images/ticketrest.png';
import sodexImg from './../../images/web-images/sodexo.png';

import {selectMealVoucher} from './../../actions/paymentActions';
import {getSavedCard} from './../../utils/PaymentGateway';


class MealVoucher extends React.Component {
    cardStatus;

    ponentDidMount() {
        this.checkCardSaved();
    }

    checkCardSaved = async () => {
        const {cookies} = this.props.cookies;
        const card = await getSavedCard(cookies.id,cookies.token);
        const {sodexo} = card.data;

        this.cardStatus = sodexo.length === 0 ? 0 : 1;
    }

    render() {
        const {sodexo, ticketrestaurant} = this.props;
        return (
            <div>
                <div class="row">
                    <div className="col-md-1 col-sm-1"></div>
                    <div class="col-md-5 col-sm-5">
                        <div class="form-group">
                            <input 
                                type="radio" 
                                name="mealvoucher"
                                {...sodexo.isActive ? {checked: true} : {}} 
                                onChange={() => this.props.selectMealVoucher('sodexo')}
                            />
                            <img src={sodexImg} height="30px" style={{marginLeft:'15px'}}/>
                        </div>
                    </div>

                    <div class="col-md-5 col-sm-5">
                        <div class="form-group">
                            <input 
                                type="radio" 
                                name="mealvoucher"
                                {...ticketrestaurant ? {checked: true} : {}} 
                                onChange={() => this.props.selectMealVoucher('ticketrestaurant')}
                            />
                            <img src={ticketImg} height="30px" style={{marginLeft:'15px'}} />
                        </div>
                    </div>
                </div>

                {
                    sodexo.isActive && this.cardStatus ? (
                       <Sodexo />
                    ): ''
                }

            </div>
        );
    }
}

const mapStateToProps = state => state.paymentpage.paymentoption.mealvouchers;
const mapDispatchToProps = {selectMealVoucher};

export default withCookies(connect(mapStateToProps,mapDispatchToProps)(MealVoucher));

But I think this isn't a perfect solution, there might be something provided by React JS, to handle the promises inside the JSX.

I googled it but I didn't find any solution on this.

Share Improve this question asked Jun 28, 2018 at 3:41 Vishal ShettyVishal Shetty 1,6682 gold badges27 silver badges43 bronze badges 1
  • 1 Can't you return promise in some method or ponentDidMount() and set it's value/flag to state ? It will be less messy rather than having it in JSX. JSX is purely for UI rendering so making async calls there would cause some inproper data to handle – Meet Zaveri Commented Jun 28, 2018 at 3:44
Add a ment  | 

1 Answer 1

Reset to default 4

React can't render from the result of a Promise. You should update a value in the ponent's state and render based on the state's value. See my example here: https://codesandbox.io/s/1vzon8r4k4. A button click sets the state to loading: true (just to show the user something while they wait), then fires off an async call. When the async call finished, the state is updated to set loading: false and set the result of the async call to a value in the state. When the state is updated, the render function is automatically called and the UI is updated to reflect the state change.

const fakePromise = () =>
  new Promise((resolve, reject) => {
    const fakeResult = "Complete";
    setTimeout(() => resolve(fakeResult), 1000);
  });

class App extends React.Component {
  constructor(props, context) {
    super(props, context);

    this.state = {
      loading: false,
      result: null
    };

    this.startAsync = this.startAsync.bind(this);
  }

  startAsync() {
    this.setState({
      loading: true
    });

    fakePromise().then(result =>
      this.setState({
        loading: false,
        result
      })
    );
  }

  render() {
    const { loading, result } = this.state;
    return (
      <div className="App">
        {!result &&
          !loading && (
            <div>
              <h1>Result Not Fetched</h1>
              <button onClick={this.startAsync} type="button">
                Fetch Result Async
              </button>
            </div>
          )}
        {loading && <h1>Fetching Result</h1>}
        {result && <h1>Result is: {result}</h1>}
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745333717a4623005.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信