Style-1
Please Check both styles
import React, { Component, createRef } from 'react'
class Click extends Component {
buttonRef = createRef();
updatedValue = 0;
clickCounter = () => {
this.updatedValue = this.buttonRef.current.value++;
console.log("upDatedValue outside of render() method= "+ this.updatedValue)
}
render() {
console.log("upDatedValue inside of render() method= "+ this.updatedValue);
return (
<div>
<button ref={this.buttonRef} onClick={this.clickCounter}>
Clicked {this.updatedValue} Times</button>
</div>
)
}
}
export default Click
Style-2
import React, { Component, createRef } from 'react'
class Click extends Component {
buttonRef = createRef();
updatedValue = 0;
render() {
let clickCounter = () => {
this.updatedValue = this.buttonRef.current.value++;
console.log("upDatedValue inside of cliclCounter() method= "+ this.updatedValue);
}
console.log("upDatedValue inside of render() method= "+ this.updatedValue);
return (
<div>
<button ref={this.buttonRef} onClick={clickCounter}>
Clicked {this.updatedValue} Times</button>
</div>
)
}
}
export default Click
None of these approach is not working. It always show "Clicked 0 Times"
Can anyone please explain why this is not working and what the solution is.
Thank you.
-Samiul Fahad
You are not updating the state of your counter. Here's a solution, since you are using class based components:
class Click extends React.Component {
constructor(props) {
super(props);
this.state = {
updatedValue: 0
}
this.clickCounter = this.clickCounter.bind(this);
}
clickCounter(){
this.setState({updatedValue: this.state.updatedValue+1})
}
render() {
return (
<div>
<button onClick={this.clickCounter}>
Clicked {this.state.updatedValue} Times</button>
</div>
)
}
}
ReactDOM.render(<Click />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Related
why state in react component isn't declared with var/let/const variable prefixes?
import React, { Component } from 'react'
class Counter extends Component {
state = {
}
render() {
return (
<>
<h1>Hello World</h1>
<button>Increment</button>
</>
)
}
}
export default Counter
They're called class fields and they were introduced as part of the ES6 revisions.
class Example extends React.Component {
state = { count: 0 };
handleClick = () => {
let { count } = this.state;
count++;
this.setState({ count });
}
render() {
const { count } = this.state;
return (
<div>
<p>You clicked {count} times</p>
<button onClick={this.handleClick}>
Click me
</button>
</div>
);
}
};
// Render it
ReactDOM.render(
<Example />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
That's just part of JavaScript class syntax. You are defining a field in the class Counter, which should be initialized to a new {} every new class instance.
You'd access it with this.state within the class, not as a regular variable.
I want the following app to print DAnce every second on the screen.
import React from 'react';
import ReactDOM from 'react-dom';
export class Sample extends React.Component {
sample(text, i) {
return <h1> DAnce</h1>;
}
render(){
return (
<div className="text-intro" id="site-type">
{setInterval(()=>this.sample('igod',1),1000)}
</div>
);
}
}
ReactDOM.render(
<Sample />,
document.getElementById('root')
);
Instead I get 5 printed on the screen.
How do I obtain the desired effect?
You could store a count in your state, and use an interval to increment this count every second and create count many Dance in the render method.
Example
class Sample extends React.Component {
state = { count: 0 };
componentDidMount() {
this.interval = setInterval(() => {
this.setState(previousState => {
return { count: previousState.count + 1 };
});
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<div className="text-intro" id="site-type">
{Array.from({ length: this.state.count }, () => <div>Dance</div>)}
</div>
);
}
}
ReactDOM.render(<Sample />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
You have to think has the text as something that is changing in your app. That is ideal for state.
I don't know what your functions sample does. But let's say you have it declared.
const sample = (text, i) => { ... };
Then you can do it like this:
class Sample extends Component {
state = {
text: sample('igod', 1),
};
componentDidMount() {
setTimeout(() => {
this.setState({
text: this.sample('igod',1)
});
}, 1000);
}
render() {
return (
<div className="text-intro" id="site-type">
{this.state.text}
</div>
);
}
}
Basically what happens is, when your component mounts you will start a timeout where every 1 second it will update the state thus updating your UI.
Try this,
import React from 'react';
import ReactDOM from 'react-dom';
export class Sample extends React.Component {
sample(text, i) {
return <h1> DAnce</h1>;
}
render(){
return(
<div className="text-intro" id="site-type">
{setTimeout(()=>{this.sample('igod',1)}, 1000)}
</div>
);
}
}
ReactDOM.render(
<Sample />,
document.getElementById('root')
);
You have used setTimeout which will be called only number of times while component renders.
You need to use setInterval to work each second.
Replace with this. Hopw this will help you.
{setInterval(()=>this.sample('igod',1),1000)}
What if you use the react lifecycle:
export class Sample extends React.Component {
sample(text, i) {
this.setState({ text });
}
render(){
return(
<div className="text-intro" id="site-type">
<h1>{this.state.text}</h1>
{setTimeout(()=>this.sample('igod',1),1000)}
</div>
);
}
I am trying to select all the text in a textarea when a component loads using React v16.3.1
Following the Refs docs I have a basic sample but this.textarea is always undefined, if I change this sample to execute the same code on a button click it works fine.
So whats going on? I had expected that after mounting the component should be available?
Sample code:
import React from "react";
class Hello extends React.Component {
constructor(props) {
super(props);
this.textarea = React.createRef();
}
componentDidMount = () => {
this.textarea.current.select();
};
render() {
return (
<div>
<textarea
className="form-control"
defaultValue="the quick brown fox."
ref={this.textarea}
/>
</div>
);
}
}
From package.json:
"react": "^16.3.1",
"react-dom": "^16.3.1",
Thanks
The documentation says:
Note
The examples below have been updated to use the React.createRef() API
introduced in React 16.3. If you are using an earlier release of
React, we recommend using callback refs instead.
If you are using an earlier release of React, u need use callback refs
class App extends React.Component {
constructor(props) {
super(props);
this.textarea = null;
this.setTextareaRef = element => {
this.textarea = element;
};
}
componentDidMount = () => {
if (this.textarea) this.textarea.select();
};
render() {
return (
<div>
<textarea
className="form-control"
defaultValue="the quick brown fox."
ref={this.setTextareaRef}
/>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Using React 16.3
class App extends React.Component {
constructor(props) {
super(props);
this.textarea = React.createRef();
}
componentDidMount = () => {
this.textarea.current.select();
};
render() {
return (
<div>
<textarea
className="form-control"
defaultValue="the quick brown fox."
ref={this.textarea}
/>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://unpkg.com/react#16.3.1/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom#16.3.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
I am trying to render a paragraph as soon as the you click the button.
Here is my code.
import React, { Component } from 'react';
class App extends Component {
constructor() {
super();
this.createText = this.createText.bind(this);
}
createText() {
return(
<p>hello friend</p>
)
}
render() {
return (
<div className="App">
<button onClick={this.createText}>Click</button>
</div>
);
}
}
export default App;
Here I am trying to render "hello friend" when the button is clicked. But is not working.
This is not the correct way because createText is a event handler it will not render the element, what you need is "Conditional rendering of elements".
Check Docs for more details Conditional Rendering.
Steps:
1- Use a state variable with initial value false.
2- Onclick of button update the value to true.
3- Use that state value for conditional rendering.
Working Code:
class App extends React.Component {
constructor() {
super();
this.state = {
isShow: false
}
this.createText = this.createText.bind(this);
}
createText() {
this.setState({ isShow: true })
}
render() {
return (
<div className="App">
<button onClick={this.createText}>Click</button>
{this.state.isShow && <p>Hello World!!!</p>}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app' />
I am trying to render a paragraph as soon as the you click the button.
Here is my code.
import React, { Component } from 'react';
class App extends Component {
constructor() {
super();
this.createText = this.createText.bind(this);
}
createText() {
return(
<p>hello friend</p>
)
}
render() {
return (
<div className="App">
<button onClick={this.createText}>Click</button>
</div>
);
}
}
export default App;
Here I am trying to render "hello friend" when the button is clicked. But is not working.
This is not the correct way because createText is a event handler it will not render the element, what you need is "Conditional rendering of elements".
Check Docs for more details Conditional Rendering.
Steps:
1- Use a state variable with initial value false.
2- Onclick of button update the value to true.
3- Use that state value for conditional rendering.
Working Code:
class App extends React.Component {
constructor() {
super();
this.state = {
isShow: false
}
this.createText = this.createText.bind(this);
}
createText() {
this.setState({ isShow: true })
}
render() {
return (
<div className="App">
<button onClick={this.createText}>Click</button>
{this.state.isShow && <p>Hello World!!!</p>}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app' />