首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用post呈现从server.js到App.js的React组件?

如何使用post呈现从server.js到App.js的React组件?
EN

Stack Overflow用户
提问于 2019-03-13 21:41:12
回答 2查看 241关注 0票数 0

我是一个反应和Javascript的初学者,所以我仍然在学习:)

我正在创建一个神奇的8球应用程序,一旦点击按钮,使用post方法,我想返回一个随机的答案(在我的server.js中的20个之一)回到同一个App.js文件.我想是作为回应吧?

如何将HTML元素(即answers[number])呈现回我的App.js (应答段落)?

Sidenote:我尝试过使用res.send()来设置它--这是否符合正确的路线?

我使用node.js和express作为服务器。

编辑:完整server.js:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-13 21:52:01

这类东西在文档中有很好的解释。

每次执行API请求时,都需要使用状态,因为它是一种副作用。我建议您阅读并理解这些文档,但是要使它在组件中工作,请在组件的开头添加以下内容:

代码语言:javascript
复制
class BlaBla extends Component {
    state = {
        response: undefined
    };

    /* Rest of component code */
}

并将获取请求更改为如下所示:

代码语言:javascript
复制
fetch('/', { method: 'POST' }).then(response => this.setState({response}));

通过添加状态,绑定也会出现问题,因此将方法声明更改为箭头函数,如下所示:

代码语言:javascript
复制
handleSubmit(event) { /* code */ }

对此:

代码语言:javascript
复制
handleSubmit = (event) => { /* code */ }

若要在答复段落中显示结果,请执行以下操作:

代码语言:javascript
复制
<p> Answer: {this.state.response} </p>
票数 0
EN

Stack Overflow用户

发布于 2019-03-13 21:52:20

基本上,您需要将获取调用的结果保存到组件状态。使用setState,它将自动触发组件的重建器并显示新的答案。

试试这个:

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

然后在渲染()中:

代码语言:javascript
复制
<div style={{display: 'flex',  justifyContent:'center', alignItems:'center'}}>
  <p>Answer:{this.state.answer}</p>
  <p>Question count: {this.state.count}</p>
</div>

编辑:

您可能需要将响应解析为json。

代码语言:javascript
复制
fetch('/', { method: 'POST' }).then(response => 
  this.setState({answer:JSON.parse(response)})
)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55151625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档