简体   繁体   English

从 React 组件调用模块化自定义 javascript 模块 function 两次。 为什么会被调用两次? 场景如下图:

[英]Calling modular custom javascript module function twice from React component. Why is it being called twice? Scenario shown below:

Hope you all are doing great.希望你们都做得很好。 I have started learning React and I have hit a road blocker and I kind of in need of your expertise here.我已经开始学习 React 并且遇到了障碍,我有点需要你的专业知识。

So the situation is like below:所以情况如下:

When I send a request to react server I can see in my console when I am trying to log the data in fetchTaskList method, the data is being printed twice whereas I have called the method only once and I am not using hooks explicitly so far.当我向反应服务器发送请求时,当我尝试在fetchTaskList方法中记录数据时,我可以在控制台中看到,数据被打印两次,而我只调用了一次该方法,并且到目前为止我没有明确使用钩子。

Could you please help me understand why this is happening?你能帮我理解为什么会这样吗? < I am a noob in JS and React. < 我是 JS 和 React 的菜鸟。 so if you could please explain in detail I will be able to understand/>所以如果你能详细解释一下我就能理解/>

Thank you!谢谢!

file structure of my project: file structure of project的项目的文件结构:项目的文件结构

App.js:应用程序.js:

import Wrapper from "./components/Wrapper";
import "./App.css";

function App() {
  return (
    <>
      <Wrapper />
    </>
  );
}

export default App;

Wrapper.js:包装器.js:

import Canvas from "./functional/Canvas";

const Wrapper = (props) => {
  return <Canvas />;
};

export default Wrapper;

Canvas: Canvas:

import { useEffect, useRef, useState, useContext } from "react";
import Card from "../ui/Card";
import Input, { NumberInput } from "../ui/Input";
import Button from "../ui/Button";
import { storeData, fetchTaskList } from "./Actions";

import style from "./canvas.module.css";
import Taskpane from "../ui/Taskpane";

import TaskContext from "../context/task-context";

let content = "init";
const Canvas = (props) => {
  // const [refresh, setRefresh] = useState(true);

  const ctx = useContext(TaskContext);
  const task = useRef();
  const priority = useRef();
  const timestamp = useRef();

  const addData = () => {
    storeData({
      task: task.current.getValue(),
      priority: priority.current.getValue(),
      date_: timestamp.current.getValue(),
    });
    task.current.setValue();
    priority.current.setValue();
    timestamp.current.setValue();
    // setRefresh(false);
  };

  let from_db = fetchTaskList(ctx.context_storage);
  console.log(from_db);
  content = <Taskpane className={style["task-container"]} task={from_db} />;

  return (
    <>
      <Card className={style["input__container"]}>
        <Input
          type="text"
          className={style["input-style__textbox"]}
          placeholder="Your activity.."
          ref={task}
        />
        <NumberInput
          placeholder="Priority"
          className={style["input-style__NumberInput"]}
          min="1"
          max="5"
          step="1"
          ref={priority}
        />
        <Input
          type="date"
          className={style["input-style__DateInput"]}
          placeholder="Pick a date"
          ref={timestamp}
        />
        <Button className={style["input-btn__add"]} onClick={addData}>
          Add
        </Button>
        {/* {content} */}
      </Card>
      {/* <Taskpane className={style['task-container']}>No task found.</Taskpane> */}
      {content}
    </>
  );
};

export default Canvas;

Actions.js: Actions.js:

import { useContext } from "react";

const Actions = (props) => {};
export default Actions;

const storeData = async function (data) {
  try {
    const response = await fetch(
      "https://mark-i-cf86f-default-rtdb.asia-southeast1.firebasedatabase.app/test_database.json",
      {
        method: "POST",
        body: JSON.stringify(data),
        headers: {
          "Content-Type": "application/json",
        },
      }
    );
    if (!response.ok) {
      console.log("Error occured!");
      return;
    }
  } catch (e) {
    console.log("Exception occured!");
  }
};

const fetchTaskList = (context_storage) => {
  try {
    fetch(
      "https://mark-i-cf86f-default-rtdb.asia-southeast1.firebasedatabase.app/test_database.json"
    )
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        if (context_storage === null) {
          console.log(data);
        }
      });
  } catch (err) {
    console.log("ERROR Occured!");
  }
  return "No task found";
};

export { storeData, fetchTaskList };

i think what's happening is that you are logging the data once in the fetchTaskList function:我认为发生的事情是您在 fetchTaskList function 中记录了一次数据:

if (context_storage === null ){
            console.log(data);
        }

and again when you call it.当你打电话给它时。

let from_db = fetchTaskList(ctx.context_storage);

console.log(from_db);控制台.log(from_db);

you can refactor your fetchTaskList function to something like this:您可以将您的 fetchTaskList function 重构为如下所示:

const fetchTaskList = async (context_storage) => {

try{
    let response = await fetch('https://mark-i-cf86f-default-rtdb.asia-southeast1.firebasedatabase.app/test_database.json');

    let data = await response.json();

    return data;
    
}catch(err){
    console.log("ERROR Occured!");
}
return "No task found";

} }

async/await is another way to deal with promises. async/await 是另一种处理 Promise 的方式。

The data is displaying twice because you are calling console.log on the data twice.数据显示两次,因为您在数据上调用了 console.log 两次。

Once inside of the function of Action.js and then again immediately after you call the function inside of Canvas.js.一次在 Action.js 的 function 内部,然后在您调用 Canvas.js 内部的 function 之后立即再次。 That is why you are seeing the data twice in the console.这就是您在控制台中看到两次数据的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM