Typechecking in React - javascript

I have a multilevel hierarchy class A-> class B-> class C through which I have to pass numbers.
The parent class is the App class like this-
import propTypes from 'prop-types';
class App extends React.Component{
constructor(props){
super(props);
this.state={
text:0,
isClicked:false
}
this.display=this.display.bind(this);
}
display(){
var num=document.getElementById('number').value;
var text=parseInt(num);
this.setState({
isClicked:true,
text:text
})
}
render(){
return(
<div className="row">
<div className="col-md-6">
<input type="text" placeholder="Enter name" value={this.state.label}/>
<input type="text" type='number' id='number'/>
<button onClick={this.display}>Click here</button>
</div>
<div className="col-md-6">
<Display click={this.state.isClicked} data={this.state.text}/>
</div>
</div>
)
}
}
App.propTypes={
text:propTypes.number,
num:propTypes.number,
data:propTypes.number
}
The Display class is the child class of App class and it is like this
import propTypes from 'prop-types';
class Display extends React.Component{
constructor(props){
super(props);
this.state={
num:this.props.data,//This value of number is coming as undefined
value:0
}
}
render(){
//console.log(this.state.data);
if(this.props.isClicked===true){
return(<DonutChart data={this.state.num}/>)
}else{
return(<DonutChart data={this.state.value}/>)
}
}
}
Display.propTypes={
data:propTypes.number,
num:propTypes.number
}
And the child class of Display class is DonutChart class which is like this
import propTypes from 'prop-types';
const DonutChart= React.createClass({
propTypes:{
data:React.PropTypes.number,
},
getDefaultProps(){
return{
value:0,
size:116
}
},
render(){
//console.log(this.props.data); This comes as 0 on the console
return(
<svg height={this.props.size} width={this.props.size}>
</svg>
)
}
})
I get this error as 'expected number but got a string' error in React. And the value of data is not getting passed to the child classes. What is the problem here?

You want this.props.data.size and your propTypes declaration in Donutchart is also erroneous also in your parent component you are only passing data instead of this.state.data. For your Donut chart, you could use a stateless functional component because you container component can handle state and props, Your chart's only job is to display info.

Related

ReactJS: setState from outside [duplicate]

This question already has answers here:
How to update the state of a sibling component from another sibling or imported component in REACT
(3 answers)
Closed 1 year ago.
This is my App.js
import React from 'react';
import './App.css'
import Tools from './components/class/Tools'
import Loading from './components/inc/Loading'
export default class App extends React.Component {
componentDidMount() {
Tools.showLoading();
}
render() {
return (
<div className="App">
<Loading />
</div>
)
}
}
Loading.js:
import React from 'react'
export default class Loading extends React.Component {
constructor(props) {
super(props)
this.state = {
display: 'none'
}
}
render() {
return (
<div className="loading" style={{display: this.state.display}}>
<span></span>
</div>
)
}
}
I want change display of Loading from Tools.js:
export default class Tools extends React.Component {
static showLoading(){ // or non-static
Loading.setState ...
}
}
How I can access and setState variable from another class or function or outside?
Your Loading and Tools components are siblings, so it is harder to pass data between them.
You should pull the state out to the parent App component, then you can pass in the setState callback method and the state.loading variable into the Tool and Loading components as a prop.
Or you can re-use your Loading component within all the other components, like so:
export default class Tool extends React.Component {
constructor(props) {
super(props)
this.state = {
loading: true
}
}
render() {
return (
<Loading isloading={loading}>
<div>
// content here
</div>
)
}
}

React state does not change

Hello I'm trying to change the state when I click the button and only when the state changes run createBattle() but the state does not change after I click the button.
At the beginning I set the state to false. The button is in Form.js with an event onClick={this.handleClick}. Then the event handleClick should set the state to true and when the state changes createBattle() in Battle.js should render the table.
Please tell me what am I doing wrong ?
Thanks
App.js
import React from "react";
import Titles from "./Components/Title";
import Form from "./Components/Form";
import Battle from "./Components/Battle";
import "./App.css";
class App extends React.Component{
state = {
startPosition : false
}
render(){
return(
<div>
<header>
<div className="meniu"></div>
</header>
<div className="wrapper">
<div className="main">
<div className="container">
<div className="title-container">
<Titles />
<div className="info">
<Form startPosition={this.state.startPosition} />
</div>
</div>
<div className="form-container">
<Battle startPosition={this.state.startPosition}/>
</div>
</div>
</div>
</div>
</div>
);
}
};
export default App;
Battle.js
import React, {Component} from "react";
import Square from "./Square";
class Battle extends Component{
constructor(){
super();
}
createBattle = () => {
let table=[];
for (let i=1; i<=10; i++){
let children = [];
for (let j=1; j<=10; j++){
children.push(<Square />)
}
table.push(<div className="board-row">{children}</div>)
}
return table;
}
render(){
console.log(this.props);
return(
<div className="center">
{this.startPosition && this.props.createBattle()}
</div>
);
}
}
export default Battle;
Form.js
import React from "react";
class Form extends React.Component{
constructor(){
super();
}
handleClick = () =>{
this.setState({
startPosition: true
});
};
render(){
console.log(this.props);
return(
<div>
<button className="button" onClick={this.handleClick}>START</button>
</div>
);
}
};
export default Form;
The state and props of a given component is not shared across other components.
If you need to communicate between components you mostly have 2 different options :
Move state logic to a common parent and pass this state as props in child components (Note that you may also need to pass some functions to allow to interact with this parent state from the child components)
Use a common state, with a framework like Redux (widely used in complex projects)
React does not support sharing of state or props values.
So you should use any of the following
React Redux
AsyncStorage

How to access state of another component

I have home component with header component how may I access the header states in home component here is the example
Header.JS
class Header extends React.Component {
constructor(props){
super(props);
this.state = {
pageNumber: 1
}
}
render() {
return (
<div className="shopping-list">
<ul>
<li>Instagram</li>
<li>WhatsApp</li>
<li>Oculus</li>
</ul>
</div>
);
}
}
Home.js
import React, {Component} from 'react';
import Header from './header';
class App extends Component {
render() {
return (
<div>
<Header /> // I need to use the states of Header in this component
</div>
)
}
}
export default App;
I need to use the states of Header in Home component, is that possible?
Does this way is good for performance?
Thank you
You need to use state lifting.
Define a method e.g. liftTheState in Header component which will lift the state of Header component by calling Home component method with required data.
class Header extends React.Component {
constructor(props){
super(props);
this.state = {
pageNumber: 1
}
}
liftTheState=()=>{
this.props.callHomeMethod(this.state.pageNumber);
}
render() {
//...
}
}
In Home :
Define a method e.g. callHomeMethod in Home component which will hold the Header component data and passed the method as a prop to Header component
class App extends Component {
callHomeMethod = (someDataFromHeader)=>{
}
render() {
return (
<div>
<Header callHomeMethod = {this.callHomeMethod}/> // pass Home method here used for state lifting.
</div>
)
}
}

Load React using by on click of a button

I wants to create a class which while load a react.js file into a div specified using the react i had not found any thing related to that on net.
Check this example:
Lets say you have 2 component App and Child, and wants to render child component on checking the checkbox, this is called conditional rendering.
app.js file, import file child.js in App component:
import Child from './child';
class App extends React.Component {
constructor() {
super();
this.showComments = this.showComments.bind(this);
this.state = {
showComponent: false,
};
}
showComments(e) {
this.setState({
showComponent: e.target.checked,
});
}
render() {
return (
<div className="add_checkbox">
<span>Enable Comments</span>
<input className="checkbox" type="checkbox" name="enable_comment" onClick={this.showComments} value="enable_comment"/>
{this.state.showComponent ? <Child/> : null}
</div>
)
}
}
child.js file:
export default class Child extends React.Component{
render(){
return(
<div>Hello</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('container'));
Check fiddle for working example: https://jsfiddle.net/ztx9kd1w/
Let me know if you need any help.

How to make/access state using props in react?

I made an app with multiple components and want their state to be accessed using parent/main app, I'm not sure how to get it. what i'm trying to do is when i change state in main "App" the component state should change. One of the component is 'checkbox' and now i want to access its state using parent app, I made multiple attempts but not getting it done. my code goes like this..
This is Main 'App' code:
import React, { Component } from 'react';
import Checkbox from './checkbox';
import Radio from './Radio';
import ToggleSwitch from './ToggleSwitch';
import PrimaryButton from './PrimaryButton';
class App extends Component {
onClick(isClicked){
isChecked:true
};
render() {
return (
<div id="form">
<Checkbox
onClick={this.onClick}
/>
<RadioButton
onClick={this.onClick}
/>
</div>
);
}
}
export default App;
The component i want to access goes like this:
import React, { Component } from 'react';
class Checkbox extends Component {
constructor(props){
super(props);
this.state={
isChecked:true
};
};
onCheck(){
this.setState({
isChecked: !this.state.isChecked
});
this.props.isClicked()
};
render() {
return (
<div>
<div
className={this.state.isChecked ? 'checked': 'unchecked'}
onClick={this.onCheck.bind(this)}
>
</div>
</div>
);
}
}
export default Checkbox;
You forgot to bind the onClick event in the app component, try this it will work :
class App extends Component {
onClick(isClicked){
console.log('isClicked', isClicked);
};
render() {
return (
<div id="form">
<Checkbox onClick={this.onClick.bind(this)}/>
</div>
);
}
}
If you already have onClick handler for the Checkbox I don't see why you couldn't just move the state up to the App component and just pass down a callback from there to the Checkbox that will update the parent state. That seems like a more React way to do it, to me.
class App extends Component {
constructor(props){
super(props);
this.state={
isChecked:true
}
}
onClick = (isClicked) => {
this.setState({isChecked: !this.state.isChecked})
}
render() {
return (
<div id="form">
<Checkbox
onClick={this.onClick}
ischecked={this.state.isChecked}
/>
</div>
);
}
}
Component
class Checkbox extends Component {
onCheck(){
this.props.onClick()
}
render() {
return (
<div>
<div
className={this.props.isChecked ? 'checked': 'unchecked'}
onClick={this.onCheck.bind(this)}
>
</div>
</div>
)
}
}

Categories

Resources