React static getDrivedStateFromProps is not working in React 16.13.1 - reactjs

Hi i am new to reactjs my react version=16.13.1.There are three files "Student.js",:Marks.js","index.js". I am trying to update state in Marks.js through Students.js using button. I am trying to update marks state through method "static getDrivedStateFromProps()".But this method is not working not even the console.log inside this method is working.Any help or suggestion will be appriciated.
**Index.js**
import React from 'react';
import ReactDOM from 'react-dom';
import Student from "./Student";
ReactDOM.render(<Student roll_no="101"/>,document.getElementById("root"));
**Student.js**
import React, { Component } from 'react'
import Marks from "./Marks";
export default class Student extends Component {
constructor(props){
super(props);
this.state={
roll_no:this.props.roll_no
}
}
handleClick=()=>{
console.log("button click");
this.setState({roll_no:(Number(this.state.roll_no)+2)});
}
render() {
return (
<div>
<h1>This rollNo is {this.state.roll_no}</h1>
<Marks roll_no={this.state.roll_no}/>
<button onClick={this.handleClick}>Click Me</button>
</div>
)
}
}
**Marks.js**
import React, { Component } from 'react';
export default class Marks extends Component {
constructor(props){
super(props);
console.log("this is marks constructor"+this.props.roll_no);
this.state={
mroll_no:this.props.roll_no
};
}
static getDrivedStateFromProps(props,state){
console.log("this is in marks in getDrivedStateFromProps");
console.log(props.roll_no);
console.log(state.mroll_no);
if(props.roll_no!==state.mroll_no){
return {mroll_no:props.roll_no}
}
return null;
}
render() {
console.log("inside marks render");
console.log("inside marks render this.props.roll_no"+this.props.roll_no);
return (
<div>
<p> in Marks the roll_no is{this.state.mroll_no}</p>
</div>
)
}
}

Related

ReactJs --- sending props to children causing issue in rendering in children. UI Rendering not happening "NewsLatest.js"

One component Landing.js has following code::
import React, { Component } from 'react'
import NewsSearch from '../NewsSearch/NewsSearch';
import NewsLatest from '../NewsLatest/NewsLatest';
import './Landing.css';
import axios from 'axios';
class Landing extends Component {
state={
newsList: []
}
componentDidMount(){
axios.get(`https://api.nytimes.com/svc/topstories/v2/home.json?api-key=7cK9FpOnC3zgoboP2CPGR3FcznEaYCJv`)
.then(res=> {
this.setState({newsList: res.data.results});
});
}
render() {
// console.log(this.state.newsList);
return (
<div className="landing text-center text-white">
<h1>News Portal</h1>
<div className="news-search">
<NewsSearch />
</div>
<div className="news-latest">
<NewsLatest newsList={this.state.newsList}/>
</div>
</div>
)
}
}
export default Landing;
When sending props to NewsLatest component, 2 values are getting passed: first as undefined and then when value comes then an array with the values.
In the "NewsLatest.js" file code is :::
import React, { Component } from 'react';
// import PropTypes from 'prop-types';
class NewsLatest extends Component {
newsTitle = (
this.props.newsList.map(item => (<h2>{item.title}</h2>))
)
render() {
console.log(this.props.newsList);
return (
<div>
<h2>News Latest....</h2>
{this.newsTitle}
</div>
);
}
}
export default NewsLatest;
Nothing is rendering on the UI. I dont know how to handle that. Kindly suggest something.
The issue you are facing is that you are not rendering anything (per se) cos newsTitle does not return anything.
In your code, newsTitle is an object but you need to make it a function.
Modifying NewsLatest should fix this though
import React, { Component } from 'react';
// import PropTypes from 'prop-types';
class NewsLatest extends Component {
newsTitle = () => (
this.props.newsList.map(item => (<h2>{item.title}</h2>))
)
render() {
console.log(this.props.newsList);
return (
<div>
<h2>News Latest....</h2>
{this.newsTitle()}
</div>
);
}
}
export default NewsLatest;

Props missing after passing to children when using draft-js

I'm kinda new to react and thought that in the constructor function, using super(props) can fully receive the props that passed by parents. But however, I can't get the string test from my parent component.
So in the parent component, I pass the string "test" as props
import React from 'react';
import Post from '../components/post';
import "../components/css/post.css"
class Bulletin extends React.Component {
render()
{
console.log(this.props);
return (
<div>
<Post test={"sent from parent"}/>
</div>
);
}
}
export default Bulletin;
And then in Post.js, I print the props in two places:
import React, { Component } from 'react';
export default class Edit extends Component {
constructor(props) {
super(props);
console.log(props);
}
render() {
console.log(this.props);
return (
<div className="editor" onClick={this.focus}>
</div>
);
}
}
The two outputs are both {className: "editor"} which is not what I need. I need the string {test: "sent from parent"} and don't know why this doesn't works for me.

How to click automatically in a button when user coming to page

import React from "react";
checkClick = () => {
console.log("clicked");
};
class Test extends React.Component {
render() {
return (
<div>
<button id="button" onClick={this.checkClick}>
click
</button>
</div>
);
}
}
export default Test;
How to click automatically on a button when user coming to page?
Here I want to click automatically above button.
I tried with:
document.getElementById("button").click()
which does not work.
You can use a ref which gives you an instance of the dom element, where you can call the click() method.
If you aren't familiar with refs, you can read all about them here: https://reactjs.org/docs/refs-and-the-dom.html
import React, { Component } from 'react'
class Test extends Component {
constructor(props) {
super(props)
this.button = React.createRef()
}
componentDidMount() {
this.button.current.click()
}
checkClick() {
console.log('clicked')
}
render() {
return (
<div>
<button ref={this.button} onClick={this.checkClick}>Click me!</button>
</div>
)
}
}
export default Test
First of all, I do not recommend you to create functions outside of React component class. In your case, you are not able to use it like this.checkClick because the checkClick function is declared outside of your React component.
The second thing, working with real DOM inside of React is basically, let's say, antipattern. React provides virtual DOM and works with it, so, I recommend you to learn about React ref API.
For your case, you can use the lifecycle componentDidMount() method. It is being called (AUTOMATICALLY, for sure) when the component has finished its first render, so, all refs are already available here and all children elements are beind mounted and present in DOM.
import React from "react"
export default class Test extends React.Component {
componentDidMount() {
document.getElementById("button").click()
}
checkClick() {
console.log("clicked!")
}
render() {
return (
<div>
<button id="button" onClick={this.checkClick}>click</button>
</div>
)
}
}
or, using refs
import React from "react"
export default class Test extends React.Component {
componentDidMount() {
this.button.click()
}
checkClick() {
console.log("clicked!")
}
render() {
return (
<div>
<button ref={button => this.button = button} onClick={this.checkClick}>click</button>
</div>
)
}
}
Use componentDidMount for that,
import React from 'react';
class Test extends React.Component {
componentDidMount(){
this.checkClick();
}
checkClick () {
console.log("clicked");
}
render() {
return (
<div>
<button id="button" onClick={this.checkClick}>click</button>
</div>
)
}
}
export default Test;

imported component is not displayed

i've a component that i import, but its not displayed on the page.
this is my app.js file. i imported the <player/>component but it is not getting displayed properly on the browser.
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import { player } from "./player";
class App extends Component {
render() {
return (
<div className="App">
<div>
<player />
</div>
</div>
);
}
}
export default App;
this is the contents of the player.js
import React from "react";
import { Button } from "evergreen-ui";
export default class player extends React.Component {
constructor(...args) {
super(...args);
this.state = {
shoot: 0
};
}
shoot() {
this.setState.shoot = Math.floor(Math.random() * Math.floor(3));
}
render() {
return (
<div>
<h1>hello there</h1>
<h1>{this.state.shoot}</h1>
<Button onClick={() => this.shoot}>Shoot another
value</Button>
</div>
);
}
}
In your code, you've exported your player component as a default export
export default class player extemds React.Component
But in your import of it in the other file, you're importing it as a named export
import { player } from "./player";
Try importing it without the curly braces as you would with a default export
import player from "./player";
You are doing two mistakes:
1. Importing the component in the wrong way
2. Rendering the component in the wrong way
Solution
The component should be imported without the curly braces
The react component "player" is supposed to start with capital letters i.e. it should be renamed as Player
Below is the working code I have tried in my local machine. It only modifies App.js
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import Player from "./player"; // imported without curly braces and with capital first letter
class App extends Component {
render() {
return (
<div className="App">
<div>
<Player /> {/* Rendering the correct way */}
</div>
</div>
);
}
}
export default App;
Sidenote
In player.js, you are setting the state in the wrong fashion, it won't work because:
setState is a method and not a object
this is not binded with method shoot. It will throw error something like "cannot read this of undefined" or something
Modify your player.js as following:
import React from "react";
import { Button } from "evergreen-ui";
export default class player extends React.Component {
constructor(...args) {
super(...args);
this.state = {
shoot: 0
};
}
shoot = ()=>{
this.setState({
shoot: Math.floor(Math.random() * Math.floor(3)),
});
}
render() {
return (
<div>
<h1>hello there</h1>
<h1>{this.state.shoot}</h1>
<Button onClick={() => this.shoot()}>Shoot another
value</Button>
</div>
);
}
}
You have two main issues:
1) You export as default and then your import is wrong.
If you export as:
export default class player extemds React.Component
Then you need to import as:
import player from "./player";
2) Components must start uppercase, otherwise React thinks that they are simple HTML tags and not components.
So you must change player to Player everywhere

Rendering Order In React

I am trying to understand the rendering order of Methods in React. I have a "persons" class and I iterate an array inside it calling a child component called "person".
My Persons.js in below
import React, { Component } from 'react';
import Person from './Person/Person';
class Persons extends Component{
constructor(props){
super(props);
console.log('[Persons.js] inside constructor',props);
}
componentWillMount(){
console.log('[Persons.js] inside componentWillMount()');
}
componentDidMount(){
console.log('[Persons.js] inside componentDidMount()');
}
render(){
console.log('[Persons.js] inside render())');
return(
this.props.persons.map((person,index)=>{
return(
<Person click={() => this.props.clicked(index)} name={person.name} age={person.age} change={ (event) => this.props.changed(event,index)} key={person.id}/>
);
})
);
}
}
export default Persons;
My Person.js is below
import React, { Component } from 'react';
import classes from './Person.css'
class Person extends Component{
constructor(props){
super(props);
console.log('[Person.js] inside constructor',props);
}
componentWillMount(){
console.log('[Person.js] inside componentWillMount()');
}
componentDidMount(){
console.log('[Person.js] inside componentDidMount()');
}
render(){
console.log('[Person.js] inside render()');
return(
<div className={classes.Person}>
<p onClick={this.props.click}>I'm {this.props.name} and {this.props.age} years old.</p>
<input type="text" onChange={this.props.change} value={this.props.name}/>
</div>
);
}
}
export default Person;
All I want to know is, why doesn't it invoke componentDidMount after render method of Person.js file? Instead, it invokes 4 times after finish iterating.
Here is the screenshot
Any idea?

Resources