Как можно рендерить компонент React из server.js в App.js, используя post? - PullRequest
0 голосов
/ 14 марта 2019

Я новичок в React и Javascript, поэтому все еще учусь:)

Я создаю волшебное приложение с 8 шарами, в котором после нажатия кнопки, используя метод post, я хочу вернуть случайноеответ (один из 20 в моем server.js) обратно в тот же файл App.js ... Я предполагаю, что в качестве ответа?

Как я могу сделать элемент HTML (то есть answers[number]) обратно вмой App.js, где мой ответ пункт?

Sidenote: Я пытался использовать res.send() для его настройки - это правильно?

Я использую node.js и express в качестве сервера.

РЕДАКТИРОВАТЬ: полный server.js:

const express = require('express')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const app = next({dev})
const handle = app.getRequestHandler()

app.prepare()
.then(() => {
  const server = express()

  server.get('/p/:id', (req, res) => {
    const actualPage = '/post'
    const queryParams = { title: req.params.id }
    app.render(req, res, actualPage, queryParams)
  })

  server.get('*', (req,res) => {
    return handle(req,res)
  })

  server.listen(3000, (err) => {
    if (err) throw err
    console.log('> Ready on http://localhost:3000')
  })

  /* Return random answer after question is submitted.*/
  server.post('/', (req,res) => {
    const answers = [
      "It is certain.",
      "It is decidedly so.",
      "Without a doubt.",
      "Yes - definitely.",
      "You may rely on it.",
      "As I see it, yes.",
      "Most likely.",
      "Outlook good.",
      "Yes.",
      "Signs point to yes.",
      "Reply hazy, try again.",
      "Ask again later.",
      "Better not tell you now.",
      "Cannot predict now.",
      "Concentrate and ask again.",
      "Don't count on it.",
      "My reply is no.",
      "My sources say no.",
      "Outlook not so good.",
      "Very doubtful.",
      "Computer says no."
    ]
    const number = Math.floor(Math.random()*21);
    console.log("Raw answer: ");
    console.log(answers[number]);
    res.status(200).send(answers[number]);
    console.log("Response: ");
    console.log(res);
  })

})
.catch((ex) => {
  console.error(ex.stack)
  process.exit(1)
})

РЕДАКТИРОВАТЬ: полный App.js:

import Layout from '../components/MyLayout.js'
import Header from '../components/Header.js'
import Link from 'next/link'
import { Component } from "react";
import { spring } from 'popmotion';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';

class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      response: undefined
    };
    this.incrementCounter = this.incrementCounter.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  componentDidMount() {
    this.setState({
      count: parseInt(localStorage.getItem("count")) || 0
    });
  }

  incrementCounter() {
    const count = this.state.count + 1;
    localStorage.setItem("count", count);
    this.setState({
      count: count
    });
  }

  handleSubmit = (event) => {
    event.preventDefault();
    fetch('/', { method: 'POST' }).then(response => this.setState({response}));
    console.log("this.state.response:");
    console.log(this.state.response);
  }

  render() {
    return (
        <main>
          <Header />
            <div style={{display: 'flex',  justifyContent:'center', alignItems:'center'}}>
              <h1 style={{ fontFamily:"Arial", fontSize:"50px" }}>Magic 8 Ball</h1>
            </div>

            <div style={{display: 'flex',  justifyContent:'center', alignItems:'center'}}>
              <form className="question-input" onSubmit={this.handleSubmit}>
                <TextField
                  id="inputquestion"
                  autoComplete="off"
                  placeholder="Ask your question..."
                  margin="normal"
                />
                <Button
                  variant="contained"
                  type="submit"
                  color="primary"
                  onClick={this.incrementCounter.bind(this)}
                  id="submitquestion"
                  style={{ width: "100px", fontSize:17 }}>Shake Me!
                </Button>
              </form>
            </div>

            <div style={{display: 'flex',  justifyContent:'center', alignItems:'center'}}>
              <p>Answer: </p>
              <p>Question count: {this.state.count}</p>
            </div>
        </main>
    )
  }
}

export default App;

Ответы [ 2 ]

0 голосов
/ 14 марта 2019

По сути, вам нужно сохранить результат вызова выборки в состояние вашего компонента. Используя setState, он автоматически запустит повторную визуализацию вашего компонента и отобразит новый ответ.

Попробуйте это:

handleSubmit(event) {
    event.preventDefault();
    // assuming the fetch works ok...
    fetch('/', { method: 'POST' }).then(response => 
      response.json().then(data => this.setState({answer:response}) )
     )
  }

затем внутри render ():

<div style={{display: 'flex',  justifyContent:'center', alignItems:'center'}}>
  <p>Answer:{this.state.answer}</p>
  <p>Question count: {this.state.count}</p>
</div>

EDIT:

Возможно, вам потребуется проанализировать ответ как json, например:

fetch('/', { method: 'POST' }).then(response => 
  this.setState({answer:JSON.parse(response)})
)
0 голосов
/ 14 марта 2019

Подобные вещи хорошо объяснены в документах .

Каждый раз, когда вы делаете запрос API, вам нужно использовать состояние, потому что это побочный эффект. Я предлагаю вам прочитать документы и понять их, но для того, чтобы это работало в вашем компоненте, добавьте это в начале вашего компонента:

class BlaBla extends Component {
    state = {
        response: undefined
    };

    /* Rest of component code */
}

И измените запрос на получение так, чтобы он выглядел следующим образом:

fetch('/', { method: 'POST' }).then(response => this.setState({response}));

При добавлении состояния у вас также будут проблемы с привязкой, поэтому измените объявление метода на функцию стрелки, вот так:

handleSubmit(event) { /* code */ }

к этому:

handleSubmit = (event) => { /* code */ }

Чтобы отобразить результат в ответном абзаце, сделайте следующее:

<p> Answer: {this.state.response} </p>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...