javascript - 如何在 React JS 中处理 JSX 内的 Promise?

标签 javascript reactjs es6-promise

这是我第一次在我的 React JS 项目中处理 JSX 内的 promise 。

这是我的组件代码。

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));

在上面,我尝试在 JSX 内调用 checkSavedCard(),但即使我返回 01checkSavedCard() 中,我看到返回的是 Promise,而不是 01

因此,我使用 .then() 并尝试根据 checkSavedCard() 返回的值渲染另一个组件。

但是,这不起作用,相反,我收到一条错误消息。

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

因此,我想出了一种不同的方法。 我创建了一个全局变量,并在 checkSavedCard() 内部,而不是返回值,而是将该值保存到全局变量中,然后在 JSX 内部检查该全局变量的值。

这种方法对我来说效果很好。

这是工作组件代码。

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;

    componentDidMount() {
        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));

但我认为这不是一个完美的解决方案,React JS 可能提供了一些东西来处理 JSX 内部的 promise 。

我用谷歌搜索了它,但没有找到任何解决方案。

最佳答案

React 无法根据 Promise 的结果进行渲染。您应该更新组件状态中的值并根据状态值进行渲染。请参阅我的示例:https://codesandbox.io/s/1vzon8r4k4 。单击按钮将状态设置为 loading: true (只是为了在用户等待时向用户显示一些内容),然后触发异步调用。当异步调用完成时,状态会更新以设置 loading: false 并将异步调用的结果设置为状态中的值。当状态更新时,会自动调用 render 函数并更新 UI 以反射(reflect)状态更改。

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.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

关于javascript - 如何在 React JS 中处理 JSX 内的 Promise?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51074374/

相关文章:

javascript - 使用 HTML CSS 和 JS 拖动对象

reactjs - 如何从 `material-ui` 导入类型?

javascript - 没有react-dom可以使用react-core吗

javascript - 使用数组对象获取最大的更大键值

javascript - 当 Promise 状态被拒绝或解决时

javascript - 如何使用 Javascript 或 Jquery 单击按钮打开文件夹位置

相当于 Clojure 的 "reductions"或 python 的 itertools.accumulate 的 Javascript

带循环的 Javascript 输出对象实例

javascript - jQuery.getJSON 的 React 版本 {

javascript - 如何使用 Promise.all 获取一组 URL?