useParam outside react component - reactjs

I am trying to pass a variable value which uses useParam hook so i can pass it to my api which set outside of the component function.
VesselComponent.js :
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { fetchComponents } from "../../../features/componentsSlice";
import TreeItem from "#mui/lab/TreeItem";
import TreeView from "#mui/lab/TreeView";
import ExpandMoreIcon from "#mui/icons-material/ExpandMore";
import ChevronRightIcon from "#mui/icons-material/ChevronRight";
import { Link, Outlet, useParams } from "react-router-dom";
import axios from "axios";
export const api = async () => {
try {
const res = await axios.get(
// here
`http://127.0.0.1:8000/api/maintenance/${vesselId}`
);
return res.data;
} catch (error) {
console.log(error);
}
};
function VesselComponents() {
// this line
const vesselId = useParams();
const { components, error, loading } = useSelector(
(state) => state.components
);
// rest of the code

You can try to pass a param to api that would help you have vesselId from other places including useParams
export const api = async (vesselId) => {
try {
const res = await axios.get(
// here
`http://127.0.0.1:8000/api/maintenance/${vesselId}`
);
return res.data;
} catch (error) {
console.log(error);
}
};
Here is how we call it
const vesselId = useParams();
api(vesselId);

You can only use react hooks at the top level inside a component. You shouldn't call useParams in your api function. Instead, you should pass it to your api function and use some state to store the response from your API. Something like this:
export const api = async (vesselId) => {
try {
const res = await axios.get(
// here
`http://127.0.0.1:8000/api/maintenance/${vesselId}`
);
return res.data;
} catch (error) {
console.log(error);
}
};
function VesselComponents() {
// this line
const vesselId = useParams();
const [vesselData, setVesselData] = useState();
const { components, error, loading } = useSelector(
(state) => state.components
);
const fetchVesselData = async () => {
try {
const res = await api(vesselId);
setVessesData(res);
} catch (e) {
// handle error
}
}
useEffect(() => {
fetchVesselData()
});

Related

SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON when Fetching Data

I am trying to fetch some data for my project, using Redux Thunk but i get the error which appears in the screenshot.
This is the error](https://i.stack.imgur.com/6Dqtm.png)
My thunk function
`
export const fetchCategoriesStart = () => createAction(CATEGORIES_ACTION_TYPES.FETCH_CATEGORIES_START);
export const fetchCategoriesSuccess = (categoriesArray) => createAction(CATEGORIES_ACTION_TYPES.FETCH_CATEGORIES_SUCCESS, categoriesArray);
export const fetchCategoriesFailed = (error) => createAction(CATEGORIES_ACTION_TYPES.FETCH_CATEGORIES_FAILED, error);
export const fetchCategoriesAsync = () => async (dispatch) => {
dispatch(fetchCategoriesStart())
try {
const response = await fetch('../../menu.json');
const categoriesArray = await response.json()
dispatch(fetchCategoriesSuccess(categoriesArray));
} catch (error){
dispatch(fetchCategoriesFailed(error));
}
}
`
The component where I dispatch the thunk function:
`
import { fetchCategoriesAsync } from "../../store/menu/menu.action";
import { useDispatch } from "react-redux";
import { useEffect } from "react";
const Menu = () => {
const dispatch = useDispatch()
useEffect(() => {
dispatch(fetchCategoriesAsync());
}, [])
}`
I tried to fetch some products from a json file using Redux Thunk and I expected the payload to be the array of the products

What is the correct way to run "const getStaticProps" with "useEffect"?

const getStaticProps is for fetching API, I want to run this with:
useEffect(()=>{
getStaticProps()
})
but I get this error:
ReferenceError: data is not defined
What is the correct way to run "const getStaticProps" with "useEffect"?
import React, { useEffect, useState } from 'react';
export const getStaticProps = async () => {
const res = await fetch('https://jsonplaceholder.typicode.com/photos');
const data = await res.json();
var i = 0;
return {
props: { test: data.slice(0, (i += 10)) },
};
};
function home({ test }) {
useEffect(() => {
getStaticProps();
});
return <h1>h1</h1>;
}
export default home;
If you meant nextjs getStaticProps method, there is no way to use both together. That method is to fetch data on server side. But useEffect will be fired after component rendering (client side).
You can await for the promise to settled and take value
CODESANDBOX LINK
import "./styles.css";
import React, { useEffect, useState } from "react";
export const getStaticProps = async () => {
const res = await fetch("https://jsonplaceholder.typicode.com/photos");
const data = await res.json();
var i = 0;
return {
props: { test: data.slice(0, (i += 10)) }
};
};
function Home({ test }) {
useEffect(() => {
async function fn() {
const result = await getStaticProps();
// Now you can use value result
console.log(result);
}
fn();
}, []);
return <h1>h1</h1>;
}
export default function App() {
return (
<div>
<Home />
</div>
);
}
As I can see, you probably want to use a variable to pass it to the view. If so, you need useState hook. https://reactjs.org/docs/hooks-state.html
Here's could be a possible solution:
import React, { useEffect, useState } from 'react';
function Home({ test }) {
const [data, setData] = useState([]);
const getStaticProps = async () => {
const res = await fetch('https://jsonplaceholder.typicode.com/photos');
const data = await res.json();
setData(data);
};
useEffect(() => {
getStaticProps();
});
return <h1>h1</h1>;
}
export default Home;
we can directly fetch the response using .then from promise in useffect
useEffect(() => {
getStaticProps().then((res) => {
console.log(res.props.test);
});
For getStaticProps no Need to call it. when you export function with name of 'getStaticProps' next automatically call it before component mount.
import React, { useEffect, useState } from 'react';
function Home({ test }) {
console.log(test);
return <h1>h1</h1>;
}
export async function getStaticProps({ params }) {
const res = await fetch('https://jsonplaceholder.typicode.com/photos');
const data = await res.json();
var i = 0;
return {
props: { test: data.slice(0, (i += 10)) },
};
};
export default Home;

React useEffect fetch data and print it out via the conosle

I want to fetch data from an API and then print it out or to display it in the return statement from my react compenent so I can have a p element that have data fetched from the api in it.
The problem is that the usestate dont get updated
The component code
import React, { useEffect } from "react"
import { newsComponentService } from "../services/newsComponentService";
const NewsComponent = () => {
const [newsComponentData, setNewsComponentData] = React.useState({});
const componentData = React.useRef("");
async function newsComponentHandler() {
let res = await newsComponentService();
//console.log(res);
setNewsComponentData(res);
//console.log(res);
}
useEffect(() => {
newsComponentHandler();
//setNewsComponentData(res);
}, [setNewsComponentData]);
console.log(newsComponentData["data"]);
return (
<p>{newsComponentData["data"]}</p>
)
}
export default NewsComponent;
The api service code
export async function newsComponentService(){
const response = await fetch("api/news-categories/1", {
method: 'GET',
headers: {
'Accept': 'application/json',
},
});
let resJson = await response.json();
//console.log(resJson);
return resJson;
}
I think the issue could be with the async behavior of the JS.
import React, { useEffect } from "react"
import { newsComponentService } from "../services/newsComponentService";
const NewsComponent = () => {
const [newsComponentData, setNewsComponentData] = React.useState({});
const componentData = React.useRef("");
useEffect(() => {
const newsComponentHandler = async () => {
let res = await newsComponentService();
setNewsComponentData(res);
}
newsComponentHandler();
}, [setNewsComponentData]);
console.log(newsComponentData["data"]);
return (
<p>{newsComponentData["data"]}</p>
)
}
export default NewsComponent;
PS. As a good practice, please put the API fetching in try-catch block in newsComponentService.js

After adding useDispatch, the code behind cannot be run

I'm using apisauce to create api for my app. And apisauce had a function call addMonitor, here: https://github.com/infinitered/apisauce#adding-monitors.
But when I add useDispatch to naviMonitor, the code behind cannot run. Specifically, I can't log the response. Bellow is my Api.js:
import apisauce from 'apisauce';
import {useDispatch} from 'react-redux';
const create = () => {
...
const naviMonitor = (response) => {
const dispatch = useDispatch();
const {status} = response || {};
if ( (status && status === 200) ) {
console.log(response);
} else {
// TODO
}
};
api.addMonitor(naviMonitor);
}
Where was I wrong?
Thank you for help me.
Have a try by returning the response object from API to the component function and use the dispatch method there as we are not allowed to use the useDispatch hook or any react hooks outside the component.
Like :
import apisauce from 'apisauce';
import {useDispatch} from 'react-redux';
const create = () => {
...
const naviMonitor = (response) => {
const {status} = response || {};
if ( (status && status === 200) ) {
console.log(response);
return response; // process response if required.
} else {
// TODO
return response; // process response if required.
}
};
api.addMonitor(naviMonitor);
}
In The component screen:
import {useDispatch} from 'react-redux';
const MyComponent = props => {
const dispatch = useDispatch();
const actionHandler = async () => {
const response = await create();
dispatch(response); // dispatch your actions here..
}
}

Trying to query my mongodb to check if a user exists and based off the respose register them

I have 2 express routes createUser that adds a new user to my mongodb and getUserByAuth0Id that searches the db for a user. I have tested them with postman and they work fine.
However in my frontend i want to call getUserByAuth0Id to check if a user is already registered or not and add them to my db as per the result.
I am having trouble using the response that returns. Currently I get back "Request failed with status code 404". How can I use this in a conditional?
My React functional element that i am trying to do this in is here:
import React, { Component, useEffect, useState } from "react";
import { useAuth0 } from "#auth0/auth0-react";
import api from "../api";
import "../App.css";
const Homepage = ({ match }) => {
const { user, isAuthenticated } = useAuth0();
useEffect(() => {
async function checkUserExists() {
if (isAuthenticated) {
const auth0Id = user.sub.split("|")[1];
try {
const response = await api.getUserByAuth0Id(auth0Id);
return response;
} catch (err) {
// console.log(err.message);
return err.message;
}
}
}
async function registerUser() {
if (checkUserExists() == "No user") {
register
}
}
registerUser();
}, []);
Here is my api/index.js:
import axios from "axios";
const api = axios.create({
baseURL: "http://localhost:3000/api",
});
export const createQuestion = (payload) => api.post(`/quizzes`, payload);
export const getAllQuestions = () => api.get(`/quizzes`);
export const getQuestionsByQuiz = (quiz) => api.get(`/quizzes/${quiz}`);
export const getQuestionById = (question_id) => api.get(`/quizzes/questions/${question_id}`);
export const updateQuestionById = (question_id, payload) => api.put(`/quizzes/${question_id}/edit`, payload);
export const deleteQuestionById = (question_id) => api.delete(`/quizzes/${question_id}`);
export const createUser = (payload) => api.post(`/users`, payload);
export const getUserByAuth0Id = (Auth0Id) => api.get(`/users/${Auth0Id}`);
const apis = {
createQuestion,
getQuestionsByQuiz,
updateQuestionById,
deleteQuestionById,
getAllQuestions,
getQuestionById,
createUser,
getUserByAuth0Id,
};
export default apis;
I think the problem is you are using async functions without react-thunk, please add it and after that dispatch your API and it will works
export const createUser = async (payload) => await api.post(`/users`, payload);
export const getUserByAuth0Id = async (Auth0Id) => await api.get(`/users/${Auth0Id}`);

Resources