簡體   English   中英

我如何使用post將React組件從server.js渲染到App.js?

[英]How can I render a React component from server.js to App.js using post?

我是React和Javascript的初學者,所以仍然在學習:)

我正在創建一個神奇的8球應用程序,在其中使用post方法單擊按鈕后,我想將隨機答案(server.js中的20個之一)返回到相同的App.js文件...我認為是回應?

如何將HTML元素(即Answers answers[number] )呈現回我的Answer段落所在的App.js中?

旁注:我嘗試使用res.send()進行設置-這是否正確?

我正在使用node.js並表示為服務器。

編輯:完整的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;

這些內容在docs中已得到很好的解釋。

每次您執行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>

基本上,您需要將fetch調用的結果保存到組件狀態。 使用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>

編輯:

您可能需要將響應解析為json例如

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM