Реагировать на изменения в магазине Redux иногда повторно, а иногда нет - PullRequest
0 голосов
/ 05 октября 2018

Так что я использую API выборки с реакцией / редукцией для выполнения вызовов API для Blockv в своих действиях и для хранения возвращенного массива объектов в моем хранилище с использованием редуктора.Мой массив объектов содержит только один уровень объектов (например, {id: 9798234982739847, имя: 220398402343 и т. Д.}).Моя таблица, которую СЛЕДУЕТ перерисовывать каждый раз при замене массива - и я использую замену, поскольку хочу полностью заменить массив в хранилище на новые - иногда только повторные рендеринг, и я могу видеть изменения, отраженные в хранилище.

Я использую промежуточное программное обеспечение Thunk.Вот что я работаю с:

store.js

import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import { createLogger } from 'redux-logger'
import urbanArcadeReducer from '../reducers/reducers'
import { loadTokens } from '../localStorage'
import { checkAuth } from '../actions/check-auth'

const persistedTokens = loadTokens();
const loggerMiddleware = createLogger();

// Store for Urban Arcade Application
const store = createStore(
    urbanArcadeReducer,
    persistedTokens,
    applyMiddleware(
        thunk,              // lets us dispatch() functions
        loggerMiddleware    // neat middleware that logs actions
    )
)

// Check for automatic login on page load
store.dispatch(checkAuth(store.getState().access_token))

export default store

redurs.js

function atoms(state = { 
    receivedAt: null, 
    atoms: []
}, action) {
    switch (action.type) {
        case UPDATE_CURR_ATOMS:
            var mappedAtoms = action.atoms.map(atom => { 
                atom = {
                    id: atom.id, 
                    gameTitle: atom.private.GameTitle,
                    highscore: atom.private.HighScore,
                    highscoreOwner: atom.private.HighScoreOwner,
                    locationName: atom.private.LocationName,
                    scoreHistory: atom.private.ScoreHistory,
                    unpublished: atom.unpublished,
                    author: atom['vAtom::vAtomType'].author,
                    description: atom['vAtom::vAtomType'].description,
                    dropped: atom['vAtom::vAtomType'].dropped,
                    lat: atom['vAtom::vAtomType'].geo_pos.coordinates[1],
                    lng: atom['vAtom::vAtomType'].geo_pos.coordinates[0],
                    owner: atom['vAtom::vAtomType'].owner,
                    template: atom['vAtom::vAtomType'].template,
                    template_variation: atom['vAtom::vAtomType'].template_variation,
                    title: atom['vAtom::vAtomType'].title,
                    when_created: atom.when_created,
                    when_modified: atom.when_modified
                }

                return atom
            })

            return {
                ...state,
                receivedAt: action.receivedAt,
                atoms: mappedAtoms
            }
        default:
            return state
    }
}

actions.js

import { 
    fetchRequest,
    fetchFailure,
    fetchSuccess,
    updateNotifier,
    updateCurrAtoms } from './action-creators'
import { bringToLogin } from './bring-to-login'


export const UPDATE_CURR_ATOMS = 'UPDATE_CURR_ATOMS'
export function updateCurrAtoms(atoms) {
    return { type: UPDATE_CURR_ATOMS, atoms: atoms.atoms, receivedAt: atoms.receivedAt }
}

/**
 * Submits request to get all arcade games using Blockv Discover Endpoint(vAtoms)
 *  
 * @returns list of arcade cabinets (vAtoms)
 */
export function getAtoms(params) {
    var access_token = params.access_token
    var from_refresh = params.from_refresh
    var responseCode = ''
    var method = 'POST'
    var url = 'https://api.blockv.io/v1/vatom/discover'
    var headers = {
        'Content-Type': 'application/json',
        'App-Id': '<App ID>',
        'Authorization': 'Bearer ' + access_token
    }
    var requestBody = {
        "scope": {
            "key": "vAtom::vAtomType.template",
            "value": "<publisher_fqdn>"
        },
        "filters": [
            {
            "filter_elems": [
                {
                "field": "vAtom::vAtomType.template",
                "filter_op": "Match",
                "value": "<publisher_fqdn>"
                }
            ]
            }
        ],
        "return": {
            "type": "*",
        }
    }

    var requestBodyJSON = JSON.stringify(requestBody)

    // Thunk middleware knows how to handle functions.
    // It passes the dispatch method as an argument to the function,
    // thus making it able to dispatch actions itself.
    return function(dispatch) {
        // First dispatch: the app state is updated to inform
        // that the API call is starting.
        dispatch(fetchRequest())

        console.log('Sending get atoms request to Blockv...');

        fetch(url, {
            method: method,
            body: requestBodyJSON,
            headers: headers
        }).then(response => {
            responseCode = response.status
            console.log(responseCode)

            return response.json()  
        }).then(data => {
            if (responseCode === 401) {
                dispatch(bringToLogin("We've logged you out. Please reauthenticate"))
                dispatch(fetchFailure('Failed to get atoms'))
            } else if (responseCode === 200) {
                var atoms = data.payload.results

                dispatch(fetchSuccess('Retrieved atoms!'))  // Array of template variations

                if (from_refresh) {
                    dispatch(updateNotifier({
                        isOpen: true,
                        message: 'Successfully retrieved games!'
                    }))
                }

                dispatch(updateCurrAtoms({
                    atoms: atoms,
                    receivedAt: Date.now()
                }))
            }
        }).catch(err => {
            console.log(err)
            dispatch(fetchFailure('Failed to get atoms'))
        });
    } 
}

MyComponent.js

...
class GameStatsModal extends Component {
  getDataAtoms = () => {
    return this.props.atoms
  }

  /**
   * Props for each row in table
   *
   * @memberof GameStatsModal
   */
  setTrProps = (state, rowInfo, column, instance) => {
    return { 
      style: {
        marginBottom: 15
      }
    }
  }

  render () {
    return (
      <OuterContainer>
        <StatsContainer>
          <InnerContainer>
            <img  
              src={RefreshIcon} 
              alt="Refresh List"
              id="refreshGames"
              className='refreshButton'
              onClick={ 
                () => { 
                  store.dispatch(getAtoms({
                    access_token: store.getState().access_token,
                    from_refresh: true
                  })) 
                }
              } 
            />
            <ReactTable
              data={this.getDataAtoms()}
              className='-highlight -striped gamesTable'
              noDataText="Click Refresh to Load Games"
              columns={columnsAtoms}
              defaultSorted={[{id: 'created', desc: true}]}
              getTrProps={this.setTrProps}
              getTdProps={this.setTdProps}
              pageSize={this.getDataAtoms().length}
              showPagination={false}
              resizable={false}
            />
          </InnerContainer>
        </StatsContainer>
      </OuterContainer>
    )
  }
}

const mapStateToProps = state => ({
  atoms: state.atoms.atoms
})

export default withRouter(connect(mapStateToProps)(GameStatsModal))

Опять же, я знаю, что делаются обновления для хранения, поэтому мой вопрося как-то мутирую где-то в предыдущем состоянии?Если нет, то возможно ли, что, поскольку у меня есть несколько вызовов диспетчеризации, выполняемых в действиях, могут ли они мешать друг другу и / или воспроизводиться повторно?не уверен, где еще искать.

Ждем любых предложений, спасибо!

1 Ответ

0 голосов
/ 05 октября 2018

я думаю, что вы мутируете государство напрямую попробуйте этот

            switch (action.type) {
    case UPDATE_CURR_ATOMS:
        var mappedAtoms = action.atoms.map(atom => { 
            // directly returning the new object
            return {
                id: atom.id, 
                gameTitle: atom.private.GameTitle,
                highscore: atom.private.HighScore,
                highscoreOwner: atom.private.HighScoreOwner,
                locationName: atom.private.LocationName,
                scoreHistory: atom.private.ScoreHistory,
                unpublished: atom.unpublished,
                author: atom['vAtom::vAtomType'].author,
                description: atom['vAtom::vAtomType'].description,
                dropped: atom['vAtom::vAtomType'].dropped,
                lat: atom['vAtom::vAtomType'].geo_pos.coordinates[1],
                lng: atom['vAtom::vAtomType'].geo_pos.coordinates[0],
                owner: atom['vAtom::vAtomType'].owner,
                template: atom['vAtom::vAtomType'].template,
                template_variation: atom['vAtom::vAtomType'].template_variation,
                title: atom['vAtom::vAtomType'].title,
                when_created: atom.when_created,
                when_modified: atom.when_modified
            }
        })

        return {
            ...state,
            receivedAt: action.receivedAt,
            atoms: mappedAtoms
        }
...