React Hooks Issue When Calling useState - reactjs

I have the following React Todo component:
import React, { useState } from 'react';
const todo = props => {
const inputState = useState('') // problem with this line
return (
<React.Fragment>
<input type="text" />
</React.Fragment>
)
}
export default todo
When I run the app I get the following error in the browser:
./src/Todo.js
Line 5: React Hook "useState" is called in function "todo" which is neither a React function component or a custom React Hook function react-hooks/rules-of-hooks
I am using create-react-app to build my app and I am using the following versions of React.
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.0"

You need to write your component name with a capital first letter for it to be seen as a Component.
import React, { useState } from 'react';
const Todo = props => {
const inputState = useState('') // problem with this line
return (
<React.Fragment>
<input type="text" />
</React.Fragment>
)
}
export default Todo

Related

React Helmet cannot be used as a JSX component

I'm trying to use react-helmet in a React Typescript component like so
import { Helmet } from 'react-helmet'
interface TestComponentProps {}
const TestComponent: React.FC<TestComponentProps> = () => {
return (
<>
<Helmet>
<title>Content</title>
</Helmet>
</>
)
}
export default TestComponent
But I'm getting a TS error 'Helmet' cannot be used as a JSX component. Shown below
I've added the following dependencies with yarn
"#types/react-helmet": "^6.1.5",
"react-helmet": "^6.1.0",
How can I fix this TS error?

React Hook function useEffect

Good Morning!
I'm starting react hooks, but it throws me the following error when wanting to use useEffect:
Line 4:5: React Hook "useEffect" is called in function "profile" which is neither a React function component or a custom React Hook function react-hooks/rules-of-hooks
The code is the following:
profile.js
import React, { useEffect } from 'react';
function profile(props) {
useEffect(() => {
document.title = props.nameAtributte;
}, [props.nameAtributte])
return (
<div style={{background:"yellow"}}>
It's my profile component {props.nameAtributte}
</div>
);
}
export default profile;
App.js
import React, {useState, useEffect} from 'react';
import Profile from './components/profile';
//import logo from './logo.svg';
//import './App.css';
function App() {
const [nombre, changeName] = useState('Juan Parez');
function nombreInput_onChanged(e){
changeName (e.target.value);
}
return (
<div className="App">
<h1>{nombre} eres digno, suficiente e ilimitado</h1>
<input type="text" name="nombreInput" id="nombreInput" value={nombre} onChange={nombreInput_onChanged} />
<Profile nameAtributte={nombre}/>
</div>
);
}
export default App;
package.json
"dependencies": {
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.5.0",
"#testing-library/user-event": "^7.2.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.3"
},
What could be happening ?
I am reviewing some solutions here, but they did not work for me.
Thank you very much for the help.
Components name must start with a Capital Letter . As your profile components name starts with 'p' react is not counting it as a valid functional component.
Just change the component name to Profile and it should work fine
One of the rules of JSX is the name of the components must proceed with an uppercase letter.
If your JSX file contains a component that is having a lowercase letter as an initial letter then React will refer to it as a built-in component like <span> or <div> not a react component.
The Dot-notation component like <UserContext.Provider> and any component which starts with a capital letter indicates that the JSX tag is referring to a React component.
That's why you were getting the error as
React Hook "useEffect" is called in function "profile" which is neither a React function component or a custom React Hook function
So, in your case, you only need to change the function name as
function Profile(){
//your code
}
You don't have to change the name of the file i.e profile.js, there is no such rule for that.
You can see the Official React hooks rule book from here.

I get the Error message: "Invalid hook call" when I try to run my React app. Can't understand why

I get the error message: Invalid hook call. Hooks can only be called inside of the body of a function component when I try to run my react app.
import React from "react";
import BarChart from "../components/BarChart";
import LineChart from "../components/LineChart";
import Navbar from "../components/Navbar";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles({
row: {
display: "flex",
flexDirection: "row"
}
});
const Index = () => {
const classes = useStyles();
return (
<div>
<Navbar />
<div className={classes.row}>
<BarChart />
<LineChart />
</div>
</div>
);
};
export default Index;
It fails in line 16 (const classes = useStyles();).
The Navbar, BarChart and LinChart components is just components that I have created and it doesn't seem like the code breaks in these components. I'm able to run my code without any error messages if iI remove line 16.
Any ideas what might help?
I tried makeStyles locally and it worked perfectly fine. Kindly check your dependencies and update them to latest then try again.
I'm currently having:
"react": "^16.8.2", "react-dom": "^16.8.2", "#material-ui/core": "^4.9.12"

React Hooks Mobx: invalid hook call. Hooks can only be called inside of the body of a function component

I am using React Hooks and when I wrap my component with observer from mobx, I am getting this error. What can be the problem? Is it possible to use mobx with React Hooks?
import classnames from 'classnames';
import { observer } from 'mobx-react';
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import ViewStore from '../../../store/ViewStore';
interface INavbarProps {
viewStore: ViewStore;
}
const Navbar = observer((props: INavbarProps) => {
const { authed } = props.viewStore;
const [drawerIsOpen, setState] = useState(false);
function toggleMenu() {
drawerIsOpen ? setState(false) : setState(true);
}
return (
<div>
<Link to="/">Home</Link>
<Link to="/admin">Admin</Link>
<Link to="/all">All</Link>
{authed ? <Link to="/">Logout</Link> : <Link to="/login">Login</Link>}
<div onClick={toggleMenu}>
Open Menu
</div>
<div className={classnames('drawer', {
drawer_open: drawerIsOpen,
})} />
<div onClick={toggleMenu} className={drawerIsOpen ? 'backdrop' : ''}></div>
</div>
);
});
export default Navbar;
It's currently not supported to use hooks with the mobx-react package since it creates a class component under the hood.
You can use the 6.0.0 release candidate that will be released soon, which does support hooks.
package.json
{
"dependencies": {
"mobx-react": "6.0.0-rc.4"
}
}
The MobX observer will result in a class component under the hood.
As per here, you can work around this by doing:
(props) => <Observer>{() => rendering}</Observer>
instead of:
observer((props) => rendering)
Example
import React from "react";
import { Observer } from "mobx-react";
const MobxFunctionalComponentObserver = props => (
<Observer
inject={stores => ({ ... })}
render={props => (
...
)}
/>
);

React ref current is NULL

I have this code taken from the official React Ref docs
import React from "react";
import { render } from "react-dom";
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// create a ref to store the textInput DOM element
this.textInput = React.createRef();
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
// Explicitly focus the text input using the raw DOM API
// Note: we're accessing "current" to get the DOM node
// this.textInput.current.focus();
console.log(this.textInput);
}
render() {
// tell React that we want to associate the <input> ref
// with the `textInput` that we created in the constructor
return (
<div>
<input
type="text"
ref={this.textInput} />
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
const A = () => {
return <div>
<CustomTextInput />
</div>
}
render(<div><A/></div>, document.getElementById("root"));
and when the focusTextInput is called it logs "current: null".
Here is the demo: https://codesandbox.io/s/wo6qjk9xk7
The code is fine since it's the exact same example present in react docs. Problem is your react-dom version is older. React.createRef() API was introduced in React 16.3 (all react related packages should be 16.3+ in order to use React.createRef()). Check this reference in docs.
Your dependencies:
"dependencies": {
"react": "16.6.3",
"react-dom": "16.2.0"
},
Problem fixed after updating react-dom to 16.6.3
Check this: https://codesandbox.io/s/n7ozx9kr0p

Resources