首页 > 解决方案 > Cannot assign retrieved json to object in ReactJS using setState and then retrieve it from state

问题描述

I am having errors of:

Werkzeug error message

This is my console log output in Chrome 80:

react-dom.development.js:12212 Uncaught TypeError: Cannot read property 'bet_id' of undefined
    at App.placeBet (App.js:116)
    at Object.App.placeWin (App.js:100)
    at onComplete (Countdown.js:99)
    at index.js:1
    at basicStateReducer (react-dom.development.js:16445)
    at updateReducer (react-dom.development.js:16591)
    at updateState (react-dom.development.js:16640)
    at Object.useState (react-dom.development.js:17363)
    at useState (react.development.js:1619)
    at i (index.js:1)
    at CountdownCircleTimer (index.js:1)
    at renderWithHooks (react-dom.development.js:16260)
    at updateFunctionComponent (react-dom.development.js:18347)
    at beginWork$1 (react-dom.development.js:20176)
    at HTMLUnknownElement.callCallback (react-dom.development.js:336)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:385)
    at invokeGuardedCallback (react-dom.development.js:440)
    at beginWork$$1 (react-dom.development.js:25780)
    at performUnitOfWork (react-dom.development.js:24695)
    at workLoopSync (react-dom.development.js:24671)
    at performSyncWorkOnRoot (react-dom.development.js:24270)
    at react-dom.development.js:12199
    at unstable_runWithPriority (scheduler.development.js:697)
    at runWithPriority$2 (react-dom.development.js:12149)
    at flushSyncCallbackQueueImpl (react-dom.development.js:12194)
    at flushSyncCallbackQueue (react-dom.development.js:12182)
    at scheduleUpdateOnFiber (react-dom.development.js:23709)
    at dispatchAction (react-dom.development.js:17076)
    at e (index.js:1)
App.js:162 get SUCC {"active":true,"bet_id":0,"id":1,"numerator":0,"stake":10,"username":"<removed from SO question>"}

As you can see, the JSON is received successfully and also this.setState() seems to be working with the received object.

The json structure (retrieved by componentDidMount(){fetch(${this.props.api}/markets){...}}):

[ 
    { 
        "bet_id":0,
        "event":"10",
        "name":"10-bet.png",
        "odds":{ 
            "numerator":10,
            "denominator":0
        }
    },
    ...
]

I assume it is because the betSlip object is not populated or is populated in the way is is not processable by the further logic. See the code (withAuth is from OKTA SDK, you can remove that part for simplicity) below.

App.js

export default withAuth(class App extends Component {
  constructor(props) {
    super(props)
    this.state={
      hasError: false,
      markets: [],
      betSlip: [],
      winSlip: []}
   }

  componentDidMount() {
    fetch(`${this.props.api}/markets`)
    .then(res => res.json())
    .then(markets => this.setState({ markets }))
    .catch((error) => {
        this.setState(this.state.hasError);
        console.error(error);
      }
    );
  }

  addToSlip = (betid) => {
    const markets = this.state.markets;
    const newBet = markets.find(market => market.bet_id === betid);
    newBet.stake = '';

    const updatedMarkets = markets.map(market => toggleActiveStatus(market, betid, true));

    this.setState({
      betSlip: [
        ...this.state.betSlip,
      newBet
      ],
      markets: updatedMarkets
    });
  }

  placeBet = (action) => {
    const singleBet = this.state.betSlip[0];
    if (action==="win") {
      const body = {
        bet_id: singleBet.bet_id,
        username: this.state.user.name,
        stake: singleBet.stake,
        numerator: "0",
        active: "True",
        event: "win"
      };
      fetch(`${this.props.api}/bets`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
        body: JSON.stringify(body)
      })
      .then((res) => res.json())
      .then((responseBetJson) => {
        this.setState({betSlip: responseBetJson})
        console.log("bet SUCC "+JSON.stringify(responseBetJson));
      })
      .catch((error) => {
        console.error(error)
        console.log("bet FAIL "+JSON.stringify(body))
      });
    } else if (action==="get") {
      fetch(`${this.props.api}/bets?bet_id=0`+
      `&username=`+this.state.user.name+
      `&stake=10`+
      `&numerator=0`+
      `&event=`+action+, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        }
      })
      .then((res) => res.json())
      .then((responseGetJson) => {
        console.log("get SUCC "+JSON.stringify(responseGetJson))
        this.setState({betSlip: responseGetJson })
      })
      .catch((error) => {
        console.error(error)
        console.log("get FAIL")
      });
    }
  }

  render() {
    if (this.state.hasError) {
      return <h1>Error occured during reading Configuration!</h1>
    }
    return (
      <div className="Body">
        <Navigation />
        <div className="App">
          <main>
            <Countdown
              placeWin={this.placeWin}
            />
          </main>
          <MarketsListContainer
            addToSlip={this.addToSlip}
            markets={this.state.markets}
          />
        </div>
      </div>
    )
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

标签: javascriptreactjsreact-propsreact-state

解决方案


推荐阅读