React Redux JSON从谷歌电子表格

React Redux JSON from Google Spreadsheet

本文关键字:谷歌 电子表格 JSON Redux React      更新时间:2023-09-26

为我们的滑雪小屋创建了一个网页,我们把它出租给人们。我有一个谷歌电子表格,上面有价格、日期和那个特定日期是否可以出租。

我之前的页面是用AngularJS写的,TabletopJS从电子表格中获取数据,但我认为用React和Redux写它会是一个很好的经验,没有TabletopJS。

我该如何从谷歌电子表格吐出的JSON中获取数据?我看过Redux的异步操作教程,但是我发现用我自己的代码很难实现。

你们有什么建议我应该怎么做吗?

这是我的angularjs代码: tabletop-config.js
'use strict';
angular
  .module('myApp')
  .config(tableTopConfig);
function tableTopConfig (TabletopProvider) {
  TabletopProvider.setTabletopOptions({
    key: 'https://docs.google.com/spreadsheets/d/1GJHfKQy24BFKNkYVjCfFtar1OCd4vJ8_TvFRheMKH90/pubhtml',
    simpleSheet: true
  });
}    

bookingController.js

(function () {
  'use strict';
  angular
    .module('myApp')
    .controller('bookingController', bookingController);
  function bookingController($scope, Tabletop) {
    var vm = this;
    Tabletop.then(function(ttdata) {
      vm.data = ttdata[0];
    });
  }
})();

您需要* redux-thunk或类似的东西来处理异步操作。下面的fetchTable函数必须使用您的API来更新以获得电子表格数据。

(*注:从技术上讲,你可以没有redux-thunk,但它只会更复杂。)

// actions/spreadsheet.js
// --- Action-creators ---
function requestSpreadsheet() {
  return {
    type: 'SPREADSHEET_REQUEST'
  }
}

function receiveSpreadsheet(data) {
  return {
    type: 'SPREADSHEET_RECEIVED',
    payload: {
      data: data
    }
  }
}

function receiveSpreadsheetError(error) {
  return {
    type: 'SPREADSHEET_FAIL',
    payload: {
      error: error
    }
  }
}
// --- API ---
function fetchTable(tableInfo) {
  // Code related to API here. Should just return a promise.
  // Someting like...
  return fetch('spreadsheet url here')
}

// --- Thunks ---
function getSpreadsheetData(tableInfo) {
  return function (dispatch, getState) {
    // Tell reducers that you are about to make a request.
    dispatch(requestSpreadsheet())
    // Make the request, then tell reducers about
    // whether it succeeded or not.
    return fetchTable(tableInfo).then(
      data => dispatch(receiveSpreadsheet(data)),
      error => dispatch(receiveSpreadsheetError(error))
    )
  }
}

然后你需要一个或多个reducer来监听这些操作并相应地更新应用程序状态。您应该考虑希望如何塑造应用程序状态。我对你的申请没有其他的假设。

// reducers/spreadsheet.js
const initialState = {
  spreadsheetData: {}
  loading: false,
  errorMsg: ''
}
function spreadsheet(state = {}, action = {}) {
  switch (action.type) {
    case 'SPREADSHEET_REQUEST':
      return {
        ...state,
        loading: true
      }
    case 'SPREADSHEET_RECEIVED':
      return {
        ...state,
        loading: false,
        spreadsheetData: action.payload.data,
        errorMsg: ''
      }
    case 'SPREADSHEET_FAIL':
      return {
        loading: false,
        errorMsg: action.payload.error 
      }
  }
}

然后你在React中有了你的视图逻辑,它将整个视图视为一个接受应用状态并返回你想要显示的HTML的函数。你需要npm install --save react-redux来允许你的React组件"监听"你的redux应用状态的变化,这样他们就会相应地重新渲染。

// containers/Spreadsheet.js
import { connect } from 'react-redux'
import SpreadsheetComponent from '../components/Spreadsheet'
// This function tells your SpreadsheetComponent about the
// parts of the app state that it should "listen" to. The 
// component will receive them as normal react props.
// These fields can be named whatever is most convenient.
function mapStateToProps(appState) {
  return {
    spreadsheetData: state.spreadsheetData,
    loading: state.loading,
    errorMsg: state.errorMsg
  }
}
// 
export default connect(mapStateToProps)(SpreadsheetComponent)
// components/Spreadsheet.js
import React from 'react';
function Spreadsheet(props) {
  return (
    <h1>Here is the spreadsheet!</h1>
    <ul>
      {props.spreadsheetData.map(row => {
        return (
          <li>
            <RowStuff row={row} />
          </li>
        )
      })}
    </ul>
  )
}

你怎么把这些东西连在一起?

// configureStore.js
import React from 'react'
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux'
import { render } from 'react-dom'
import thunk from 'redux-thunk';
import App from './components/App'
import rootReducer from './reducers/index';
const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);
render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)