【问题标题】:React for displaying the log file in real-time (Flask backend)React 用于实时显示日志文件(Flask 后端)
【发布时间】:2020-07-02 21:01:01
【问题描述】:

我有一个工作代码(Flask + 纯 JS),它实时显示不断增长的日志文件。 我在将其转换为 ReactJS 时遇到问题。

app.py(Flask,工作代码,没问题)

@app.route('/stream')
def stream():
    def generate():
        fname="/Users/xxx/tmp/log.txt"
        with open(fname) as f:
            while True:
                yield f.read()
                sleep(1)
    return 
    app.response_class(generate(), mimetype='text/plain')

app.run()

index.html(纯JS,没问题)

<pre id="output"></pre>
<script>
    var output = document.getElementById('output');
    var xhr = new XMLHttpRequest();
    xhr.open('GET', '');
    xhr.send();

    setInterval(function() {
        output.textContent = xhr.responseText;
    }, 1000);
</script>

以下是我尝试将其转换为 React。

在 MyPage.jsx 上,我放置了“显示实时日志”按钮。 当用户单击此按钮时,应弹出模态对话框并显示日志。

文件:MyPage.jsx

import Modal from 'react-bootstrap/Modal'
import { Button } from 'react-bootstrap'

const showLog = (e) => {
    render(<ModalLog />,  document.getElementById('output'));
}

const MyPage = () => {
  return (
    <div>
          <div id="output"></div>
          <button type="button" onClick={showLog}>Show Real Time Log</button>
</div
}

function ModalLog() {
  const [show, setShow] = useState(true);

  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);

  return (
    <>
      <Modal show={show} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Real Time Log</Modal.Title>
        </Modal.Header>
        <Modal.Body> Log file live update goes here </Modal.Body>
        <Modal.Footer>
          <Button variant="primary" onClick={handleClose}>
            Close
          </Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}

问题:

  1. 将当前位于我的 index.html 中的 JS 代码放入 MyPage.jsx 的什么位置?

  2. 当我按下“显示实时日志”按钮时,模式仅显示第一次,在我关闭后它不再显示。我明白它是什么,因为调用了 handleClose(),但是如何解决呢?

【问题讨论】:

    标签: reactjs flask real-time


    【解决方案1】:

    (1) 将当前位于我的 index.html 中的 JS 代码放入 MyPage.jsx 的什么位置?

    简单的答案是你不知道。它直接操作 DOM,这是一种严重的反应反模式。您可以将其转换为 useEffect 挂钩以获取最新的日志数据并将其保存到组件状态以进行渲染。

    const [logs, setLogs] = useState('');
    useEffect(() => {
      // asynchronous function to fetch logs
      const fetchLogs = async () => {
        try {
          const logResponse = await /* logic to fetch log */
          setLogs(logResponse);
        } catch {
          // just don't update state, or set an error message in state,
          // basically anything you want to do to handle errors
        }
      }
    
      // setup interval to fetch logs
      const intervalTimer = setInterval(fetchLogs, 1000);
    
      // function to clean up effect when component unmounts
      return () => clearInterval(intervalTimer);
    }, []); // empty dependency array to run when mounted
    

    (2) 当我按下“显示实时日志”按钮时,模态仅显示第一次,关闭后它不再显示。我明白它是什么,因为 handleClose() 被调用,但如何解决它?

    显示模态的初始状态是true。如果模态是否打开(而不是模态),我会稍微重构逻辑以使MyPage 保持状态。将showhandleClose 作为道具传递给ModalLog。无需将模态渲染到另一个 DOM 元素中,我相信 react-bootstrap 会为您创建一个门户。您可以简单地将其渲染到您的组件中。

    const MyPage = () => {
      const [show, setShow] = useState(false);
    
      const handleClose = () => setShow(false);
      const handleShow = () => setShow(true);
    
      return (
        <div>
          <div id="output"></div>
          <button type="button" onClick={handleShow}>Show Real Time Log</button>
          <ModalLog show={show} onHide={handleClose} />
        </div>
      );
    }
    
    function ModalLog({ show, onHide }) {
      return (
        <>
          <Modal show={show} onHide={onHide}>
            <Modal.Header closeButton>
              <Modal.Title>Real Time Log</Modal.Title>
            </Modal.Header>
            <Modal.Body> Log file live update goes here </Modal.Body>
            <Modal.Footer>
              <Button variant="primary" onClick={handleClose}>
                Close
              </Button>
            </Modal.Footer>
          </Modal>
        </>
      );
    }
    

    建议:放置日志状态和逻辑以获取和显示日志在模式中,因为您似乎只关心在模式打开并且有模式关闭时在后台获取它们没有意义。

    【讨论】:

      猜你喜欢
      • 2018-03-28
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 1970-01-01
      • 2018-07-20
      • 1970-01-01
      • 1970-01-01
      • 2021-02-06
      相关资源
      最近更新 更多