Как исправить получить запрос и ответ с целым HTML - PullRequest
0 голосов
/ 20 января 2019

Я новичок в реакции, редуксе и во всем остальном, и я борюсь с некоторыми проблемами.Моя первая проблема заключается в том, что я получаю от Axios запрос «получить» в качестве ответа всей моей стороной.(Я думаю, что мой веб-пакет создает некоторые проблемы) Вторая проблема заключается в том, что моя функция Axios не работает с ошибкой «this.props.getBranch не является функцией».

Я пытался исправить проблемы и некоторое время искал без решения ... Так что было бы здорово, если бы вы могли мне помочь.

мой код MultistepФорма

import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import RiskDetails from "./Step1/RiskDetails";
import { getBranch } from "../../actions/riskActions";

class RiskForm extends Component {
  constructor(props) {
    super(props);
    this.state = {
      step: 1,
      risikoName: "",
      risikoBereich: "",
      risikoKlasse: "",
      branche: ""
    };

    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

  nextStep() {
    let step = this.state.step;
    this.setState({ step: step + 1 });
  }

  prevStep() {
    let step = this.state.step;
    this.setState({ step: step - 1 });
  }

  onChange(e) {
    this.setState({ [e.target.name]: e.target.value });
  }

  onSubmit(e) {
    e.preventDefault();
  }

  render() {
    const { step } = this.state;
    const { risikoName, risikoBereich, risikoKlasse, branche } = this.state;
    const values = { risikoName, risikoBereich, risikoKlasse, branche };
    switch (step) {
      case 1:
        return (
          <RiskDetails
            nextStep={this.nextStep}
            onChange={this.onChange}
            values={values}
            getBranch={getBranch}
          />
        );
    }
  }
}

RiskForm.propTypes = {
  getBranch: PropTypes.func.isRequired
};

export default connect(
  state => {
    return {};
  },
  { getBranch }
)(RiskForm);

мой рискДетали

import React, { Component } from "react";
import { Grid, Form } from "semantic-ui-react";
import PropTypes from "prop-types";

class RiskDetails extends Component {
  componentWillMount() {
    this.props.getBranch().then(res => {
      console.log(res);
    });
  }

  render() {
    const { value } = this.props;
    return (
      <Grid container>
        <Grid.Row>
          <Grid.Column width={8}>
            <Form>
              <Form.Select
                fluid
                label={value.branch}
                //options={this.state.branch}
                placeholder={value.branch}
              />
            </Form>
          </Grid.Column>
        </Grid.Row>
      </Grid>
    );
  }
}

RiskDetails.propTypes = {
  getBranch: PropTypes.func.isRequired
};

export default RiskDetails;

мои действия

import axios from "axios";
import { FETCH_BRANCH } from "./types";

export function createRisk(event) {
  return dispatch => {
    return axios.post("/api/risk", event);
  };
}

export function fetchRiskDetails(risk) {
  return {
    type: FETCH_BRANCH,
    risk
  };
}

export function getBranch() {
  return dispatch => {
    console.log("starting get request")
    return axios.get("/api/risk").then(res => {
      dispatch(fetchRiskDetials(res.data));
      console.log(res.data);
    });
  };
}

редуктор

import { FETCH_BRANCH } from "../actions/types";

const initialState = {
  risk: {}
};

export default (state = initialState, action = {}) => {
  switch (action.type) {
    case FETCH_BRANCH:
      return {
        risk: action.risk
      };
    default:
      return state;
  }
};

сервер index.js

import express from "express";
import path from "path";
import bodyParser from "body-parser";
import mongoose from "mongoose";
import cors from "cors";

//WEBPACK
import webpack from "webpack";
import webpackMiddleware from "webpack-dev-middleware";
import webpackHotMiddleware from "webpack-hot-middleware";
import wepbackConfig from "../webpack.config.dev";

//IMPORT ALL API ROUTES
import authRoute from "./routes/auth";
import signUpRoute from "./routes/signup";
import companyRoute from "./routes/company";
import riskRoute from "./routes/risk";
import recommendationRoute from "./routes/recommendation";

let app = express();

const compiler = webpack(wepbackConfig);

app.use(
  webpackMiddleware(compiler, {
    hot: true,
    publicPath: wepbackConfig.output.publicPath,
    noInfo: true
  })
);
app.use(cors());
app.use(express.static(path.join(__dirname, "dist")));
app.use(webpackHotMiddleware(compiler));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// SET UP YOUR DB FOR THE API
// =============================================================================


var url = "mongodb://localhost:27017/blubb";

mongoose
  .connect(
    url,
    { useNewUrlParser: true, useCreateIndex: true }
  )
  .then(() => console.log("connected to DB"))
  .catch(err => console.log(err));

app.get("/*", (req, res) => {
  res.sendFile(path.join(__dirname, "./index.html"));
});

// ROUTES FOR OUR API
// =============================================================================
app.use("/api/auth", authRoute);
app.use("/api/risk", riskRoute);

app.listen(3000, () => console.log("running"));

часть риска

import express from "express";
import {
  validatePostInput,
  validateDeleteInput
} from "../shared/validation/risk";
import Risk from "../models/risk";
import authenticate from "../middleware/authenticate";

let router = express.Router();

router.get("/", (req, res) => {
  console.log("hi form server");
  Risk.find(function(err, risks) {
    if (err) {
      console.log(err);
    } else {
      res.status(400).json(risks);
    }
  });
});

//create new risk
router.post("/", authenticate, (req, res) => {
  const { errors, isValid } = validatePostInput(req.body);
  console.log(req.body);
  if (isValid) {
    const { risikoName, risikoBereich, risikoKlasse, createdBy } = req.body;
    var newRisk = new Risk({
      risikoName,
      risikoBereich,
      risikoKlasse,
      createdBy
    });

    // save the risk
    newRisk.save(function(err) {
      if (err) {
        return res.status(500).json({ error: err });
      }
      res.json({ success: true });
    });
  } else {
    res.status(400).json(errors);
  }
});

//delete risk
router.delete("/", (req, res) => {
  const { errors, isValid } = validateDeleteInput(req.body);
  if (isValid) {
    const { id } = req.body;
    Risk.remove({ _id: id }, function(err, risk) {
      if (err) return res.status(500).json({ error: err });
      res.json({ success: true });
    });
  } else {
    res.status(400).json(errors);
  }
});

export default router;

конфигурация webpack

import path from "path";
import webpack from "webpack";

export default {
  mode: "development",
  entry: [
    "webpack-hot-middleware/client",
    path.join(__dirname, "client/index.js")
  ],
  output: {
    filename: "bundle.js",
    path: "/",
    publicPath: "/"
  },
  plugins: [
    new webpack.NoEmitOnErrorsPlugin(),
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin()
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        include: [
          path.join(__dirname, "client"),
          path.join(__dirname, "server/shared")
        ],
        loaders: ["react-hot-loader/webpack", "babel-loader"]
      },
      {
        test: /\.css$/,
        loader: "style-loader!css-loader"
      },
      {
        test: /\.s[a|c]ss$/,
        loader: "sass-loader!style-loader!css-loader"
      },
      {
        test: /\.(jpg|png|gif|jpeg|woff|woff2|eot|ttf|svg)$/,
        loader: "url-loader?limit=100000"
      }
    ]
  },
  resolve: {
    extensions: [".js"]
  }
};

=== РЕДАКТИРОВАТЬ === Вот мой ответ на запрос

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Tool</title>
        <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    </head>
    <body>
        <div id="app"></div>
        <script src="bundle.js"></script>
    </body>
</html>

1 Ответ

0 голосов
/ 21 января 2019

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

app.get("/*", (req, res) => {
  res.sendFile(path.join(__dirname, "./index.html"));
});

Похоже, он будет обрабатывать все запросы, поэтому описание маршрутизатора после этого никогда не будет достигнуто. Попробуйте изменить это с помощью:

app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname, "./index.html"));
});

Если вам действительно нужно, чтобы /*, поместите еще один в самую последнюю строку объявления маршрутизатора.


1011 * второй *:

Вы звоните props внутри componentWillMount(), который обычно недоступен на этом жизненном цикле. Даже обычно это все еще не доступно в componentDidMount() жизненном цикле. На основании некоторых статей, которые я прочитал, componentWillMount() устарела в текущей версии React. Я предлагаю вам не использовать его. Есть 2 способа решения этой проблемы, я могу порекомендовать вас следующим образом:

  1. метод componentDidMount ()

Использование componentDidMount() жизненного цикла. В этом методе вы должны указать setTimeout(), чтобы дать компоненту время для получения реквизита.

componentDidMount() {

    setTimeout(()=>{

      this.props.getBranch().then(res => {
        console.log(res);
      });
    },
    100);//Try with 0 first ( not put this parameter ), if it is not works, try to increase by 100, 200 etc.
}

2. Метод getDerivedStateFromProps ()

Старый способ использует componentWillRecieveProps(), но, поскольку он устарел, я рекомендую использовать getDerivedStateFromProps(). На этом этапе жизненного цикла не требуется setTimeout() трюк. Потому что реквизит уже должен быть в наличии.


Для справки, вот хорошая статья о устаревших жизненных циклах React: https://hackernoon.com/problematic-react-lifecycle-methods-are-going-away-in-react-17-4216acc7d58b


==== ОБНОВЛЕНИЕ 22 января '19 ======

Просто предложение, обычно мы можем просто вызывать избыточные действия непосредственно к компоненту, вместо этого передавая их как реквизиты. Таким образом, вы можете очистить RiskForm компонент от проводки Redux следующим образом:

import React, { Component } from "react";
// import { connect } from "react-redux"; //!!! move connect() inside RiskDetails instead
import PropTypes from "prop-types";
import RiskDetails from "./Step1/RiskDetails";
// import { getBranch } from "../../actions/riskActions"; //!!!!Move this to RiskDetails component

class RiskForm extends Component {
  constructor(props) {
    super(props);
    this.state = {
      step: 1,
      risikoName: "",
      risikoBereich: "",
      risikoKlasse: "",
      branche: ""
    };

    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

  nextStep() {
    let step = this.state.step;
    this.setState({ step: step + 1 });
  }

  prevStep() {
    let step = this.state.step;
    this.setState({ step: step - 1 });
  }

  onChange(e) {
    this.setState({ [e.target.name]: e.target.value });
  }

  onSubmit(e) {
    e.preventDefault();
  }

  render() {
    const { step } = this.state;
    const { risikoName, risikoBereich, risikoKlasse, branche } = this.state;
    const values = { risikoName, risikoBereich, risikoKlasse, branche };
    switch (step) {
      case 1:
        return (
          <RiskDetails
            nextStep={this.nextStep}
            onChange={this.onChange}
            values={values}
            // getBranch={getBranch}//!!! Don't need this props, import inside RiskDetails directly
          />
        );
    }
  }
}

RiskForm.propTypes = {
  getBranch: PropTypes.func.isRequired
};

/*
export default connect(
  state => {
    return {};
  },
  { getBranch }
)(RiskForm);*/

export default RiskForm;//You can remove connect() and leave this as dumb component

Затем сделайте ваш RiskDetails компонент контейнером / умным компонентом следующим образом (обратите внимание на комментарии, которые я сделал с восклицательным знаком / '!'):

import React, { Component } from "react";
import {connect} from 'react-redux';//!!! Import redux here
import { Grid, Form } from "semantic-ui-react";
import PropTypes from "prop-types";
import { getBranch } from "../../actions/riskActions";//!!! Import action creator here

class RiskDetails extends Component {
  componentWillMount() {
    getBranch().then(res => {//Call the action creator directly instead using props
      console.log(res);
    });
  }

  render() {
    const { value } = this.props;
    return (
      <Grid container>
        <Grid.Row>
          <Grid.Column width={8}>
            <Form>
              <Form.Select
                fluid
                label={value.branch}
                //options={this.state.branch}
                placeholder={value.branch}
              />
            </Form>
          </Grid.Column>
        </Grid.Row>
      </Grid>
    );
  }
}

RiskDetails.propTypes = {
  getBranch: PropTypes.func.isRequired
};

export default connect(null)(RiskDetails);//!!! Connect this component with redux
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...