简体   繁体   English

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

[英]Pass database data from express.js server to react.js component

This is a react app with an express.js backend. 这是一个带有express.js后端的React应用。 I have a mysql database connected to my server.js file and it seems to be connected fine. 我的mysql数据库已连接到我的server.js文件,并且似乎连接正常。 My issue is I want to pass that data to my react app and display it there. 我的问题是我想将该数据传递到我的应用程序并在其中显示。

My server.js database connection 我的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(); 

});

So this should grab the 'list_items' records from the database 因此,这应该从数据库中获取“ list_items”记录

Below is my react.js code. 下面是我的react.js代码。 I would like to display the records under the grocery list h3. 我想在购物清单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;

I know this is a simple concept but I am new to backend development. 我知道这是一个简单的概念,但是我对后端开发是陌生的。 The tutorials I have found have gotten me to this point, but I have had an issue finding one that simply explains how to pass and display data from the backend to frontend. 我找到的教程已经使我明白了这一点,但是我遇到了一个问题,那就是找到一个简单地说明如何从后端到前端传递和显示数据的问题。

You want to make a GET request to your backend to asynchronously fetch the data. 您想向后端发出GET请求以异步获取数据。 If you want the data when your App component first mounts, you can use fetch in componentDidMount to call to your backend endpoint. 如果您希望在首次安装App组件时获得数据,则可以在componentDidMount使用fetch来调用后端端点。 Here's an example, with a loading fallback and basic error handling: 这是一个示例,具有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 won't reject on HTTP error status (404, 500), which is why the first .then is a little odd. fetch不会拒绝HTTP错误状态(404,500),这就是第一个.then有点奇怪的原因。 The .catch will log the response here with the status, but if you want to see the error message from the server, you'll need to do something like this: .catch将在此处记录响应的状态,但是,如果您想查看来自服务器的错误消息,则需要执行以下操作:

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

See See https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch for more information, or explore other data fetching libraries like axios . 有关更多信息,请参见https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch ,或浏览其他数据获取库,例如axios

**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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM