React / Redux with AntDesign focus on component - javascript

I'm kind stuck on this feature that i have do implement on my app. I need to set focus in a component on componentDidMount() or something similar.
i'm already try some suggestions like:
componentDidMount(){
this.nameDiv.focus();
}
<div ref={(div) => { this.nameDiv = div; }}>
for focus or similar for (Antdesign component) focus.
or something like that:
document.getElementById("mytext").focus();
<input type="text" id="mytext"/>
usualy i'm receiveing errors on my console: "Cannot read property 'focus' of undefined"
So the question: How can i set focus on a react / antDesign component?

Please look to following code. I'm sure this would help you.
import React from "react";
import ReactDOM from "react-dom";
class TestFocus extends React.Component {
componentDidMount = () => {
this.refs.focusedInput.focus();
};
render = () =>
<React.Fragment>
<input placeholder="I don't want focus :/" />
<br />
<input ref="focusedInput" placeholder="Please focus on me :B" />
</React.Fragment>;
}
ReactDOM.render(<TestFocus />, document.getElementById("root"));
Tested with react 16.8.6 & react-dom 16.8.6
Let me know, if this helps.

Related

Navigate to welcome page after login page using React Router Dom v6

I'm a beginner learning React and using React v 17.0.2, react-router-dom v 6.0.2. I'm following a course made for react-router-dom v4. I'm not able to get page navigation working if I try to navigate from a successful login to append a welcome message to the url. In v4 this is achieved by a {this.props.history.push("/welcome") method. I'm not able to something equivalent in V6. Specifically, I would like to know how to handle the loginClicked method.
Based on the helpful guidance from Himanshu Singh, I tried the following:
import { computeHeadingLevel } from '#testing-library/react'
import React, { Component } from 'react'
import { BrowserRouter as Router, Routes, Route, useNavigate } from 'react-router-dom'
class TodoApp extends Component {
render() {
return (
<div className="TodoApp">
<Router>
<Routes>
<Route path="/" exact element={<LoginComponent />} />
<Route path="/enlite" element={<LoginComponent />} />
<Route path="/welcome" element={<WelcomeComponent />} />
</Routes>
</Router>
{/* <LoginComponent /> */}
</div>
)
}
}
class WelcomeComponent extends Component {
render() {
return <div>Welcome to Enlite</div>
}
}
class LoginComponent extends Component {
constructor(props) {
super(props)
this.state = {
username: 'testuser',
password: '',
hasLoginFailed: false,
showSuccessMessage: false
}
this.handleChange = this.handleChange.bind(this)
this.loginClicked = this.loginClicked.bind(this)
}
handleChange(event) {
this.setState(
{
[event.target.name]
: event.target.value
})
}
**loginClicked() {
if (this.state.username === 'testuser' &&
this.state.password === 'dummy') {
function HandlePageNav() {
let navigate = useNavigate()
navigate('/welcome')
}
**HandlePageNav();**
}
else {
this.setState({ showSuccessMessage: false })
this.setState({ hasLoginFailed: true })
}
}**
render() {
return (
<div>
{this.state.hasLoginFailed && <div>Invalid Credentials</div>}
{this.state.showSuccessMessage && <div>Welcome to Enlite</div>}
User Name: <input type="text" name="username" value={this.state.username} onChange={this.handleChange} />
Password: <input type="password" name="password" value={this.state.password} onChange={this.handleChange} />
<button onClick={this.loginClicked}>Login</button>
</div>
)
}
}
export default TodoApp
This gives the following 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.
Basically calling hooks in class components is not supported. I also tried to completely do away with the function like this:
loginClicked() {
if (this.state.username === 'testuser' &&
this.state.password === 'dummy') {
let navigate = useNavigate()
navigate('/welcome')
}
else {
this.setState({ showSuccessMessage: false })
this.setState({ hasLoginFailed: true })
}
}
This gives a compile error:
Line 85:32: React Hook "useNavigate" cannot be called in a class
component. React Hooks must be called in a React function component or
a custom React Hook function react-hooks/rules-of-hooks Line 89:13:
'HandlePageNav' is not defined
no-undef
The above makes me wonder if I need to refactor my entire code into a function component or if there's a way to achieve this page navigation but keeping the class component. Other than that I would appreciate any help or insights on this problem. Thanks in advance.
UseNavigate Hook will not work here because hooks are meant to be used in functional components not class components.
What you can do for now is, since no proper doc is provided for class component
Try to use Functional Components : the most easiest way
Use a HOC component around the class component and pass history and other necessary props to it through that component.
Note: Here I tried second approach. You can follow this: https://codesandbox.io/s/snowy-moon-30br5?file=/src/App.js

React basics - updating var and using it in render doesn't work

New to ReactJS with experience in android
I simply set a value to variable on input change and use it in display
But the input freezes and new value is also not applied
I also declared the var msg outside render function so it isn't initialized every time
This is certainly not how react works and i'm doing trivial mistake but it may be so trivial that there are no answers out there
What am i doing wrong
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
var msg = "initial value";
const Message = () => {
return (
<div>
<input
type="text"
value={msg}
placeholder="Enter a message"
onChange={(e) => {
alert(e.target.value);
msg = e.target.value;
}}
/>
<p>
<strong>{msg}</strong>
</p>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<Message />, rootElement);
Here's a link to live demo
https://codesandbox.io/s/usestate-01-forked-f2vdq?file=/src/index.js:0-543
React is not tracking your variable, so you will never see an update. You need to use component state, which will cause React to be aware of it and trigger a render when it changes. I've updated your code to use the useState hook:
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
var msg = "initial value";
const Message = () => {
const [message, setMessage] = useState(msg);
return (
<div>
<input
type="text"
value={message}
placeholder="Enter a message"
onChange={(e) => {
alert(e.target.value);
setMesage(e.target.value);
}}
/>
<p>
<strong>{msg}</strong>
</p>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<Message />, rootElement);
We set the initial internal state based on the msg value, and then update that internal state on change, which will cause a re-render
Nothing has told React that it needs to re-render the component.
The variable has changed, but it isn't watching the variable.
This is what state is for. Changing the state explicitly informs React that it needs to check to see if anything should be updated in the DOM. Define the variable with a state hook.
const Message = () => {
let [msg, setMsg] = useState("initial value");
return (
<div>
<input
type="text"
value={msg}
placeholder="Enter a message"
onChange={(e) => {
alert(e.target.value);
setMsg(e.target.value);
}}
/>
<p>
<strong>{msg}</strong>
</p>
</div>
);
};
Typically, variables are contained only within the classes that use them, instead of making a global variable. Full Working Demo of what I am proposing.
The state is a data object that holds whatever an instance of that class needs to work with. You have a message component, so, if we make it store a message in its state, that message value will be used anywhere in the render() function whenever used. So, we can do value={this.state.msg}, as well as <h1>{this.state.msg}</h1>. The state and component lifecycle are key to good ReactJS development.
React is stateful, as we say. If you put value="hello!", it's the same to ReactJS as putting <h1>hello!</h1>. Unless the state says that has changed because of a setState() call, ReactJS sees no reason for anything in the display to change. Only by value={this.state...} and <h1>{this.state....}</h1> are we able to make anything dynamic.
If you make a state like this, notice here we are setting a default...
constructor(props) {
super(props);
this.state = {'msg':'Initial Message'};
}
Then in your input, you can display it, like...
<input
type="text"
value={this.state.msg}
And also in the display of the value, like...
<strong>{this.state.msg}</strong>

Unable to render functional component with React Hooks

I'm new to react hooks. I'm trying to use the following component as the filter input element for one of the columns in a ReactTable component.
import React, { useState } from 'react'
import DatePicker from 'material-ui/DatePicker/DatePickerDialog'
import '../styles/style.less'
export default function DateRange({ startLabel = 'From', endLabel = 'To' } = {}) {
const [open, setOpen] = useState(false)
return (
<div className="date-range">
<input type="text" placeholder={startLabel} onClick={() => setOpen(true)} />
<input type="text" placeholder={endLabel} />
<DatePicker open={open} />
</div>
)
}
but the render fails with the following error:
Uncaught Invariant Violation: 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:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

ReactJS and autofocus

I have a react-bootstrap modal with an <input>. I want to set the autofocus attribute on the <input>
The following works fine, but shows a warning in the console
<input type="text" autofocus='true' />
Warning: Invalid DOM property `autofocus`. Did you mean `autoFocus`?
The following options do not work, in the sense that they do not focus the input when opening the modal:
<input type="text" autoFocus='true' />
<input type="text" autoFocus={true} />
<input type="text" autoFocus />
What is the recommended way of setting autofocus. Or how should I mute the warnings for the example that works well?
Note: This is react 16.8.6
If you're using React Hooks, add useCallback() to your component and add a ref={callback} to the form control:
import React, { useCallback } from 'react'
function InputComponent() {
const autoFocus = useCallback(el => el ? el.focus() : null, [])
return <input type="text" ref={autoFocus} />
}
export default InputComponent
You can replace the <input> with a React Bootstrap FormControl too.
Refs is what you want,
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount(){
this.myRef.current.focus();
}
<input type="text" ref={this.myRef} />
If you are using react hooks, you could write your own simple auto focus hook:
import { useEffect, useState } from "react";
export const useAutoFocus = (inputId: string) => {
const [initialized, setInitialized] = useState(false);
useEffect(() => {
if(!initialized) {
document.getElementById("email").focus();
setInitialized(true);
}
});
};
and the simply use e.g.
useAutoFocus("email")
in your form.

Bundle.js not recognizing one of my files?

Please bear with me because I am a javascript newbie, and just starting to learn react.
I am trying to make a small app but I keep getting an error that one of my files is not found... specifically this:
bundle.js:56 Uncaught Error: Cannot find module "./components/search_bar"
My file structure is that I have my index.js in a folder called src, then my search bar(search_bar.js) in a folder called components. I have triple checked the spelling on them but I continue to get this error.
This is my index.js
import SearchBar from './components/search_bar';
import React from 'react';
import ReactDOM from 'react-dom';
//Create a componant (some /HTML)
const API_KEY = 'AIzaSyC3Z3qTpvAacDLYEIxaueKflFJbWvdIHsw';
const App = () => {
return (
<div>
<SearchBar />
</div>
);
}
// Put that componant on the page (the DOM)
ReactDOM.render(<App />, document.querySelector('.container'));
And this is my search_bar.js
import React, { Component } from 'react';
class SearchBar extends Component {
contructor(props) {
super(props);
// when user updates the search bar this term will get updated.
this.state = { term: ''};
}
render() {
//update state
//use set state everywhere besides constructor!!
return (
<div>
<input onChange={event => this.setState({term: event.target.value})}
/>
Value of the input: {this.state.term}
</div>
);
}
}
export default SearchBar;
Any Ideas as to what I am doing wrong here?
Can you confirm the following directory structure?
my_project/src/index.js
my_project/src/components/search_bar.js
It seems like your current directory structure might instead look like this:
my_project/src/index.js, my_project/components/search_bar.js
AHHH I left an 's' out of constructor... so search_bar.js was unable to compile. I have been looking at this for about an hour now...

Categories

Resources