Been quite stuck for the past week or so and cannot find any answers to my issue. Today I started doing some proper investigating. It looks like Axios is not working when firing events. This also does not work on my main PC either which makes me think it's actually a bug with Axios.
I have already tried:
Reinstalling Axios independently
Uninstalling all global dependencies I have
Creating a new React App
Checking the events are firing (which they are)
Checking my network tab (nothing shows up)
My post request is working fine when just calling it as a function:
import React from "react";
import axios from "axios";
import "./App.css";
function App() {
const makeRequest = () => {
axios.post("http://localhost:5000");
};
makeRequest();
return <div className="app"></div>;
}
export default App;
Backend output: There was a post request!
However, my code does not work when using events, this goes for onClick and onSubmit (that's what I have tested anyway):
import React from "react";
import axios from "axios";
import "./App.css";
function App() {
const makeRequest = () => {
axios.post("http://localhost:5000");
};
return (
<div className="app">
<button onClick={makeRequest}>Post Request</button>
</div>
);
}
export default App;
No backend output or frontend output. Help would be much appreciated!
Edit: Something I forgot to mention was that fetch works absolutely fine, but I'd really rather use Axios where possible.
Change your const to a function and call it with an object passthrough method.
import React from "react";
import axios from "axios";
import "./App.css";
function App() {
function makeRequest (){
axios.post("http://localhost:5000");
};
return (
<div className="app">
<button onClick={() => makeRequest()}>Post Request</button>
</div>
);
}
export default App;
Try to add more console.log calls to grab more debug data from frontend - it can help to solve the problem.
import React from "react";
import axios from "axios";
import "./styles.css";
export default function App() {
const makeRequest = () => {
const result = axios
.post("https://jsonplaceholder.typicode.com/users")
.then((result) => {
console.log("Result", result);
})
.catch((error) => console.error("Error", error))
.finally(() => console.log("Request has been made"));
console.log("Result should be a Promise object", result);
};
return (
<div className="app">
<button onClick={makeRequest}>Post Request</button>
</div>
);
}
The code snippet above works totally fine. Check the code snippet here, and try to run it on your environment. If the information in console logs will not appear or either didn't help – dig into your environment and tools which you use to transpile JSX code, build JS and add that information to the question. Probably the problem is hidden somewhere in there.
Kindly check if you have "proxy": "localhost:5000" in your react app package.json file, this will allow React to proxy API requests to the Node.js server built with Express.
5000 is the node server port.
The problem is that your're passing the funcion instead of calling it.
I would try using an arrow funcion in onClick likt this :
onclick={()=> makeRequest()}
I can see you are not invoking the function with (), it should be makeRequest()
Related
I have a simple server that listens on port 8000 and all it does is to return the name of the files inside a directory in this format:
{'Files': ['file1', 'file2', ...]}
I have a React app, that fetches the data using the useEffect hook and then places the response with the useState hook.
The problem is that, on the first try it works perfectly, and maybe on the second time as well, but when I refresh for the third time (or more) it just disappears! and I see an error message on the chrome devtools:
Uncaught TypeError: Cannot read properties of undefined (reading 'map')
The React code is:
import './App.css';
import {useEffect, useState} from "react";
function App() {
const [file, setFile] = useState();
useEffect(() => {
async function fetchData() {
const files = await fetch('http://localhost:8000/get_directory?dir=E:\\Learning\\LearningNetworking\\MD')
const file_json = await files.json()
setFile(file_json.File)
}
fetchData()
}, [])
return (
<div className="App">
<header className="App-header">
{file.map(file_name => <p>{file_name}<br/></p>)}
</header>
</div>
);
}
export default App;
I really don't know what's going on, maybe there's a race condition and the react app tries to render the list before fetching it? But doesn't the React useEffect hook knows when to fetch again and when not?
I tried using the nullish coalescing on this line:
const file_json = await files.json() ?? []
instead of:
const file_json = await files.json()
The server (if needed for debugging reasons) written in fastapi:
from pathlib import Path
from fastapi import FastAPI, Request
from starlette.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(CORSMiddleware,
allow_origins=['*'])
#app.get('/get_directory')
def directory_tree(request: Request):
path = request.query_params.get('dir', None)
return {'Files': [file.name for file in Path(path).iterdir()]}
I'm pretty sure I've got something wrong here in my understanding of React, I am a newbie so I would appreciate your help! Any searches online did not find exactly this problem (maybe it's because I couldn't phrase the problem very well... sorry if it has been asked before!).
The problem is coming from your client code. As you defined it, initially file is undefined. And since fetching data is asynchronous, sometimes the render happens before you get the data. One way to solve this issue is to initiate your state like this:
const [file, setFile] = useState([]);
I have a NextJS app. I want to add a function that can redirect to any page using nextjs routing.
For example, after finishing signup I want to redirect to a certain page.
If I create this function (reusable everywhere) :
import { useRouter } from 'next/router'
const goTo = (href) => {
const router = useRouter()
router.push(href)
}
I want to add this to my signup Logic, the problem is that I break React Hooks rules :
react-dom.development.js?ac89:14906 Uncaught (in promise) Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
And effectively useRouter is a React Hook, and I'm trying to call it outside a React function, as stipulated here https://reactjs.org/docs/hooks-rules.html it will not work.
How can I then have a routing solution for NextJS to be callable in regular Javascript ?
So If you're using purely React.js (without Next.js on top of it), you can simple do it this way:
Import React from 'react'
export const handleRoutes = (url) => {
const history = React.useHistory()
return history.push(url)
}
Then You'd import this regular js function in any of your react files, like this:
import { handleRoutes } from 'fileName.js'
<button onClick={() => handleRoutes("/routeToBeRedirectedTo")}> Click to redirect </button>
However when using Nextjs I'm not sure that the above way would work. My personal method would be simply implementing this function (in a utility.js file):
export const handleRedirect = (router, url) => {
return router.push(url)}
Then just importing the function & useRouter hook in the file you want:
import { handleRedirect } from "./utility.js"
import { useRouter } from "next/router"
const router = useRouter
Then inside your JSX return statement:
<button onClick={() => handleRedirect(router, "/routeToBeRedirectedTo")}> Click to redirect </button>
And if it's a redirect after sign in/sign up, just simply useEffect like so:
// depends if you're storing your user credentials in your local storage or cookies, this example below would be if your User credentials are stored in localstorage
const user = JSON.parse(localstorage.getItem("user"))
UseEffect(() => {
if (user) return handleRedirect(router, "/routeToBeRedirectedTo")
}, [user])
My App was working fine and suddenly i got this error.
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
import { useContext } from "react";
import jwtDecode from "jwt-decode";
import AuthContext from "./context";
import authStorage from "./storage";
const useAuth = () => {
const { user, setUser } = useContext(AuthContext);
const logIn = (authToken) => {
const user = jwtDecode(authToken);
setUser(user);
authStorage.storeToken(authToken);
};
const logOut = () => {
setUser(null);
authStorage.removeToken();
};
return { user, logIn, logOut };
};
export default useAuth;
All looks fine. except maybe actually importing React
import React, { useContext } from "react";
I know you don't need this for React from React 17, but there's no official statement from react native saying they use the new JSX compiler that doesn't require the import statement
also check the AuthContext file you imported
I started a project with next js and typescript. I have a main component that I call it in the index.js page I use the getStaticProps function in the main component getStaticProps returns a prop object and when I log this prop in my main component I received undefined in my console.
I want to know using the getStaticProps in the component is wrong and I have just to use that function in pages or not.
I am a newbie in next js and I would be very grateful if anyone could help me.
this is my main component
import React from 'react';
import {IMain} from "../../../../interfaces/components/IMenu/IMain";
const Main:React.FC<IMain> = (props) => {
console.log(props);
return (
<div>
</div>
);
};
export async function getServerSideProps() {
return {
props: {
data: 'ggwp'
}
};
}
export default Main;
and this is my index.js page
import Text from "./../components/ui/Text/Text";
import Button from "../components/ui/Button/Button";
import Main from "../components/Menu/Desktop/Main/Main";
const Home = () => {
return <Main/>;
};
export default Home;
getStaticProps can only be exported from a page. You can’t export it from non-page files.It will not work if you add getStaticProps as a property of the page component.
https://nextjs.org/docs/basic-features/data-fetching
Here's a possible solution:
Using a node script (like predev) to fetch your content and store it in JSON files in your project, then reference those JSON files in your component.
Posted about it here:
https://dev.to/brewhousedigital/nextjs-getstaticprops-with-components-f25
Solution
used react's useEffect() for component
and for page getStaticProps() of next.js
after combine the two will have hybrid page
The code below gives
Uncaught Error: You must pass a component to the function returned by connect. Instead received undefined
List.js
import React from 'react';
import { connect, bindActionCreators } from 'react-redux';
import PostList from '../components/PostList'; // Component I wish to wrap with actions and state
import postList from '../Actions/PostList' //Action Creator defined by me
const mapStateToProps = (state, ownProps) => {
return state.postsList
}
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({"postsList":postList},dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(PostList);
PostList.js
import React from 'react'
export const PostList = (props) => {
return <div>List</div>
}
Please help me with a solution?
You are doing import PostList from '../components/PostList'; so you need to use export default in your PostList.js file.
Otherwise you need to do import { PostList } from '../components/PostList';.
To whoever is interested, here is a nice article about es6 import/export syntax: http://www.2ality.com/2014/09/es6-modules-final.html
Not related to the asker specifically, but if you're facing this error, it's worth to check if you have the connect() syntax right:
const PreloadConnect = connect(mapStateToProps, {})(Preload);
export default PreloadConnect;
Note that Preload, is passed as a IIFE parameter.
More details can be found here.
There might be three reasons, that are summarized as follows:
Circular dependencies between components
Wrong usage of export and export default then imported the wrong way
Used the connect function wrongly, passed the wrong parameters
In my case is was Circular dependencies, and the circular-dependency-plugin helped me fix it.
In my case it was Expo server that sometimes doesn't catch filesaves on Windows (probably) and it was seening old version of the component I've tried to connect (I had no export there yet probably). Re-saving my component without really touching anything fixed the issue.
Restarting Expo server with cleaned cache would probably help as well.
In my case, it was because of the usage of enums (TypeScript).
Try without enums in your code.
Reason : Enums can go undefined during runtime.
Link to Related Question
Hope it solves your problem :)