在set.state发生之前,React渲染发生了异步问题

时间:2017-11-30 05:51:09

标签: reactjs

我在处理异步问题时遇到了一些麻烦。渲染发生在将状态设置为getStepContent(0)之前,当我将其传递给组件(CartInfo)时,导致我无法访问状态值。有什么想法吗?

class Cart extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      order: [],
      error: null,
      finished: false,
      stepIndex: 0
    };
  }

  componentWillMount() {
    Meteor.call("orders.getLastOrder", (error, response) => {
      if (error) {
        this.setState(() => ({ error: error }));
        console.log(error);
      } else {
        this.setState(() => ({ order: response }));
        console.log(this.state.order);
      }
    });
  }

  goBack = () => this.props.history.push("/shop");
  goCart = () => this.props.history.push("/cart");

  handleNext = () => {
    const { stepIndex } = this.state;
    this.setState({
      stepIndex: stepIndex + 1,
      finished: stepIndex >= 2
    });
  };

  handlePrev = () => {
    const { stepIndex } = this.state;
    if (stepIndex > 0) {
      this.setState({ stepIndex: stepIndex - 1 });
    }
  };

  getStepContent(stepIndex) {
    let { order } = this.state;

    switch (stepIndex) {
      case 0:
        while (!order) {
          return getStepContent(0);
        }
        return <CartInfo CartInfo={order} />;
      case 1:
        return "What is an ad group anyways?";
      case 2:
        return "This is the bit I really care about!";
      default:
        return "You're a long way from home sonny jim!";
    }
  }

  render() {
    const { finished, stepIndex, order } = this.state;
    const contentStyle = { margin: "0 16px" };

    return (
      <CartPage pageTitle="Cart" history goBack={this.goBack}>
        <div className="CartHomePage">
          <div style={{ width: "100%", maxWidth: 700, margin: "auto" }}>
            <Stepper activeStep={stepIndex}>
              <Step>
                <StepLabel>Confirm your order</StepLabel>
              </Step>
              <Step>
                <StepLabel>Where should we send it to?</StepLabel>
              </Step>
              <Step>
                <StepLabel>Enjoy!</StepLabel>
              </Step>
            </Stepper>
            <div style={contentStyle}>
              {finished
                ? <p>
                    <a
                      href="#"
                      onClick={event => {
                        event.preventDefault();
                        this.setState({ stepIndex: 0, finished: false });
                      }}
                    >
                      Click here
                    </a>{" "}
                    to reset the example.
                  </p>
                : <div>
                    {this.getStepContent(stepIndex)}
                    <div style={{ marginTop: 12 }}>
                      <FlatButton
                        label="Back"
                        disabled={stepIndex === 0}
                        onClick={this.handlePrev}
                        style={{ marginRight: 12 }}
                      />
                      <RaisedButton
                        label={stepIndex === 2 ? "Finish" : "Next"}
                        primary={true}
                        onClick={this.handleNext}
                      />
                    </div>
                  </div>}
            </div>
          </div>
          <div>
            {/* {order.map((item, i) => <div key={i}> {item.name}  
                      {item.price} {item.quantity}</div>)} */}
            {/* {this.state.order[0]} */}
          </div>
        </div>
      </CartPage>
    );
  }
}

export default Cart;

这是我将其传递给

的组件
import React from "react";
import { withRouter } from "react-router";

const CartInfo = ({ CartInfo }) =>
  <div>
    {CartInfo[0].name}
  </div>;
export default withRouter(CartInfo);

这是我目前得到的错误代码&#34; CartInfo.jsx:6未捕获TypeError:无法读取属性&#39; name&#39;在CartInfo&#34;

中未定义

1 个答案:

答案 0 :(得分:1)

看起来您在获取数据之前尝试访问CartInfo[0].name,这会引发错误。您可以将CartInfo组件更改为以下内容:

const CartInfo = ({ CartInfo }) => {
 if (CartInfo[0]) {
   return(
     <div>
       {CartInfo[0].name}
     </div>;
    );
  }
}

这样组件将返回null,然后当获取订单数据时,它将重新呈现,CartInfo[0]将不会被定义。

另一种方法是使用lodash _.get返回undefined,而不是在尝试访问undefined属性时抛出错误。