将数据库数据从express.js服务器传递到react.js组件

时间:2019-01-16 03:54:15

标签: mysql node.js reactjs express

这是一个带有express.js后端的React应用。我的mysql数据库已连接到我的server.js文件,并且似乎连接正常。我的问题是我想将该数据传递到我的React应用并在其中显示。

我的server.js数据库连接

app.get('api/listitems', (req, res) => {     

connection.connect();    
connection.query('SELECT * from list_items', (error, results, fields) => {    
    if (error) throw error;    
    res.send(results)    
});  
connection.end(); 

});

因此,这应该从数据库中获取“ list_items”记录

下面是我的react.js代码。我想在购物清单h3下显示记录。

import React, { Component } from 'react';
import './App.scss';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: ['first item']
    };

  }

  render() {
    return (
      <div className="App">
        <h3>Grocery List</h3>
        {this.state.data}
      </div>
    );
  }
}

export default App;

我知道这是一个简单的概念,但是我是后端开发的新手。我找到的教程已经使我明白了这一点,但是我遇到了一个问题,那就是找到一个简单地说明如何从后端到前端传递和显示数据的问题。

2 个答案:

答案 0 :(得分:0)

您要向后端发出GET请求以异步获取数据。如果您想在首次安装App组件时获取数据,可以使用fetch中的componentDidMount来调用后端端点。这是一个具有loading后备和基本错误处理功能的示例:

class App extends Component {
  state = {
    data: [],
    loading: true,
    error: false
  }
  ...
  componentDidMount() {
    // Pick whatever host/port your server is listening on
    fetch('localhost:PORT/api/listitems')
      .then(res => { // <-- The `results` response object from your backend
        // fetch handles errors a little unusually
        if (!res.ok) {
          throw res;
        }
        // Convert serialized response into json
        return res.json()
      }).then(data => {
        // setState triggers re-render
        this.setState({loading: false, data});
      }).catch(err => {
        // Handle any errors
        console.error(err);
        this.setState({loading: false, error: true});
      });
  }

  render() {
    return (
      <div className="App">
        <h3>Grocery List</h3>
        // The app will render once before it has data from the
        // backend so you should display a fallback until
        // you have data in state, and handle any errors from fetch
        {this.state.loading ? <p>Loading...</p>
          : this.state.error ? <p>Error during fetch!</p>
          : (
              <ul>
                this.state.data.map(item => <li>{item}</li>)
              </ul>
            )}
      </div>
    );
  }
}

fetch不会拒绝HTTP错误状态(404、500),因此第一个.then有点奇怪。 .catch将在此处记录响应的状态,但是,如果您想查看来自服务器的错误消息,则需要执行以下操作:

if (!res.ok) {
  return res.text().then(errText => { throw errText });
}

有关更多信息,请参见See https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch,或浏览其他数据获取库,例如axios

答案 1 :(得分:0)

**index.js**

import React from 'react';
import { render } from 'react-dom';
import App from './components/app';
import { BrowserRouter } from 'react-router-dom'
import { Provider } from 'react-redux';
import store, { history } from './store';

const route = (
  <Provider store={store}>
  <BrowserRouter>
        <App />
  </BrowserRouter>
  </Provider>
)
render(route,document.getElementById('app'))

**action/listItemAction.js**

export const ListItemSuccess = (data) => {
    return {type: 'GET_LIST_ITEMS'};
}

export const getListItems = () => {
    return (dispatch) => {
        return axios.get('http://localhost:5000/api/listitems')
        .then(res => {
           dispatch(ListItemSuccess(res));
        })
        .catch(error=>{
            throw(error);
        })      
    };
}

**reducers/listItems.js**

const listItems = (state = [], action) => {
  switch(action.type){
    case 'GET_LIST_ITEMS':
      return action.res.data;
    default:
      return state;
  }
}

export default listItems;

**store.js**

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk'
import listItems from './reducers/listItems.js';

const store = createStore(listItems,  compose(
    applyMiddleware(thunk),
    window.devToolsExtension ? window.devToolsExtension() : f => f
  ));

export default store;

**App.js**

import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import './App.scss';
import getListItems from './action/listItemAction.js

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      data: [],
      isLoading: true,
    };

  }
  componentWillMount() {
    this.props.getListItems().then(() => {
      this.setState({data: this.props.listItems, isLoading:false});
    }).catch(error => {
        throw(error);
    });
  }
  render() {
    return (
      <div className="App">
        <h3>Grocery List</h3>
        {this.state.isLoading ? <p>Loading...</p>
          : this.state.error ? <p>Error during fetch!</p>
          : (
              <ul>
                this.state.data.map(item => <li>{item}</li>)
              </ul>
            )}
      </div>
    );
  }
}

const mapStateToProps = (state) => {
    return {
      listItems: state.listItems
    };
};
const mapDispatchToProps = (dispatch) => {
    return {
        getListItems: bindActionCreators(getListItems, dispatch),
    };
};

export default connect(mapStateToProps,mapDispatchToProps)(App);