派遣Redux Thunk重新渲染React组件

时间:2019-11-16 20:08:43

标签: react-redux

我正在尝试实现体育博彩过滤器,但是在尝试根据我传递给thunk的特定于运动的密钥派遣thunk以重新呈现页面时陷入困境。我有一个下拉列表,其中包含单击侦听器,这些侦听器在父组件(GamesList)中调度处理程序。我注意到,即使单击DropdownList组件中的NFL列表项,动作创建者(gotKey)仍会返回默认键('americanfootball_ncaaf')。任何帮助或指示将不胜感激。谢谢!

Redux Store

import axios from 'axios'
require('../../secrets')

const GOT_GAMES = 'GOT_GAMES'
const GOT_MONEYLINES = 'GOT_MONEYLINES'
const GOT_KEY = 'GOT_KEY'

const gotGames = games => ({type: GOT_GAMES, games})
const gotMoneyLines = games => ({type: GOT_MONEYLINES, games})
const gotKey = key => ({type: GOT_KEY, key})

const defaultSportKey = 'americanfootball_ncaaf'
const apiKey = process.env.API_KEY

export const getGames = (key = defaultSportKey) => async dispatch => {
  try {
    const {data} = await axios.get(
      `https://api.the-odds-api.com/v3/odds/?apiKey=${apiKey}&sport=${key}&region=us&mkt=spreads`
    )
    dispatch(gotGames(data))
    dispatch(gotKey(key))
  } catch (error) {
    console.error(error)
  }
}

export const getMoneyLines = (key = defaultSportKey) => async dispatch => {
  try {
    const {data} = await axios.get(
      `https://api.the-odds-api.com/v3/odds/?apiKey=${apiKey}&sport=${key}&region=us&mkt=h2h`
    )
    dispatch(gotMoneyLines(data))
    dispatch(gotKey(key))
  } catch (error) {
    console.error(error)
  }
}

const gamesState = {
  spreadGames: [],
  moneylineGames: [],
  sportKey: ''
}

const gamesReducer = (state = gamesState, action) => {
//   console.log('action' + action)
  switch (action.type) {
    case GOT_GAMES:
      return {...state, spreadGames: action.games}
    case GOT_MONEYLINES:
      return {...state, moneylineGames: action.games}
    case GOT_KEY:
      return {...state, sportKey: action.key}
    default:
      return state
  }
}

export default gamesReducer

GamesList主要组件

import React from 'react'
import {connect} from 'react-redux'
import {getGames, getMoneyLines} from '../store/games'
import SingleGame from './SingleGame'
import DropdownList from './DropdownList.js'

class GamesList extends React.Component {
  constructor() {
    super()
    this.handler = this.handler.bind(this)
  }

  componentDidMount() {
    this.props.getGames()
    this.props.getMoneyLines()
  }

  handler(key) {
    this.props.getGames(key)
    this.props.getMoneyLines(key)
  }

  render() {
    // console.log(this.state)
    const spreadList = this.props.spreadGames.data
    const moneylineList = this.props.moneylineGames.data
    if (!spreadList || !moneylineList) {
      return <div>loading</div>
    } else {
      return (
        <div>
          <DropdownList handler={this.handler} />
          {spreadList.map((game, index) => (
              (Date.now().toString().slice(0, -3) < game.commence_time) ? 
            <div key={index}>
              <SingleGame
                spreads={game.sites[0]}
                homeTeam={game.home_team}
                teams={game.teams}
                timeStart={game.commence_time}
                moneylineGame={moneylineList[index]}
              />
            </div> : null
          ))}
        </div>
      )
    }
  }
}

const mapStateToProps = state => ({
  spreadGames: state.games.spreadGames,
  moneylineGames: state.games.moneylineGames,
  sportKey: state.games.sportKey
})

const mapDispatchToProps = dispatch => ({
  getGames: () => dispatch(getGames()),
  getMoneyLines: () => dispatch(getMoneyLines())
})

export default connect(mapStateToProps, mapDispatchToProps)(GamesList)

DropdownList组件

import React from 'react'

export default class DropdownList extends React.Component {
  constructor(props) {
    super()
    this.state = {
      listOpen: false
    }
    this.showList = this.showList.bind(this)
    this.hideList = this.showList.bind(this)
  }

  showList(event) {
    event.preventDefault()
    this.setState({listOpen: true}, () => {
      document.addEventListener('click', this.hideList)
    })
  }

  hideList() {
    this.setState({listOpen: false}, () => {
      document.addEventListener('click', this.hideList)
    })
  }

  render() {
    return (
      <div>
        <div type="button" onClick={this.showList}>
          Select A Sport
        </div>
        {this.state.listOpen ? (
          <ul>
            <li
              onClick={() => {
                this.props.handler('americanfootball_nfl')
              }}
            >
              NFL
            </li>
            <li
              onClick={() => {
                this.props.handler('americanfootball_ncaaf')
              }}
            >
              NCAA
            </li>
          </ul>
        ) : (
          <li>test</li>
        )}
      </div>
    )
  }
}

1 个答案:

答案 0 :(得分:0)

您没有在mapDispatchToProps中传递密钥

const mapDispatchToProps = dispatch => ({
  getGames: key => dispatch(getGames(key)), // <-- forward key
  getMoneyLines: key => dispatch(getMoneyLines(key)) // <-- forward key
})

react-redux为此提供了一个更好的api,您只需直接传递动作创建者即可

export default connect(mapStateToProps, { getGames, getMoneyLines })(GamesList)

https://react-redux.js.org/api/connect#example-usage