Property for react component is not defined - reactjs

After running this code - I got the exception that "title" is not defined. I checked that api returns correct data. And on the debug mode I noticed that render() from Idea component is running earlier than getting the data from API. Can you explain why is it working in this way? And what options I have for resolving this issue?
Thanks
'use strict';
const React = require('react');
const ReactDOM = require('react-dom');
const client = require('./client');
class App extends React.Component {
constructor(props) {
super(props);
this.state = {map: {}};
}
componentDidMount() {
client({method: 'GET', path: '/api/maps/1'}).done(response => {
this.setState({map: response.entity._embedded.map});
});
}
render() {
return (
<Map map={this.state.map}/>
)
}
}
class Map extends React.Component {
render() {
return (
<div id="map_header">
<AddIdeaButton></AddIdeaButton>
<Idea idea={this.props.map.root}></Idea>
</div>
);
}
}
class AddIdeaButton extends React.Component {
render() {
return (
<a id="btn_add">
</a>
);
}
}
class Idea extends React.Component {
render() {
<div id="root">{this.props.idea.title}</div>
}
}
ReactDOM.render(
<App />,
document.getElementById('react')
);

Asynchronous request for data takes some time during which React still renders Map and Idea components. You can simply render Idea conditionally when data is available:
<div id="map_header">
<AddIdeaButton></AddIdeaButton>
{this.props.map.root && (
<Idea idea={this.props.map.root}></Idea>
)}
</div>

Related

React JS Inheritance get data

Hi I am developing an application with React JS.
I have a problem.
TopBottomCard.js
export default class TopBottomCard extends Component {
constructor(props){
super(props)
}
getEnlem(){
return this.props.enlem
}
render() {
return (
<div>
example</div>
)}
Map.js
import TopBottomCard from './TopBottomCard'
export default class Map extends TopBottomCard {
constructor(){
super(this)
}
render() {
const top = new TopBottomCard()
const url = 'https://www.example.com/map.html?'+top.getEnlem+''
console.log(url);
return (
<div style={{height:'100vh'}}>
</div>
)
}
}
When I go to the localhost: 3000 / map page I get an output like this.
Output:
https://www.example.com/map.html?function () { [native code] }
When I change the "url" variable on the Map.js page as follows, it gives an error.
const url = 'https://www.example.com/map.html?'+top.getEnlem()+''
Error code: TypeError: Cannot read property 'enlem' of undefined
How do I solve this?
When you create 'Map' class, make sure the constructor get the props and pass them to the parent, using super(this) will not do the trick.
Also make sure you actually send props to the class you instantiate so it will not be undefined.
class TopBottomCard extends React.Component {
constructor(props){
super(props)
}
getEnlem(){
return this.props.enlem
}
render() {
return (
<div>example</div>
)
}
}
class Map extends TopBottomCard {
constructor(props) { // get the props in this constructor as well
super(props) // and pass them to the parent constructor
}
render() {
const top = new TopBottomCard({}) // you need to send props so it will not be undefined in the component
const url = 'https://www.example.com/map.html?' + top.getEnlem() + ''
return (
<div style={{height:'100vh'}}>
</div>
)
}
}

Accessing variable from imported class from another React script

I'm importing a class from another script in my main React App, and would like to access a variable within that class from the main App. Basically the user types something into a textbox, then clicks a button to add that value to a variable. In the main App I import that class, then have another button to print those values (selectedvalues). I'm not entirely sure how to do it, but this is my code so far:
Class I am importing:
import React, { Component } from 'react';
class MyModule extends Component {
constructor() {
super();
this.state = {
selectedValues: '',
}
}
addValue() {
this.selectedValues += document.getElementById('textBox1').value + ', '
return this.selectedValues
}
render() {
return(
<div>
<input type='text' id='textBox1' />
<button onClick={() => this.addValue()}>Add Value</button>
</div>
)
}
}
export default MyModule
And where I would like to actually access that value
import React, { Component } from 'react';
import MyModule from './myModule.js'
class App extends Component {
constructor() {
super();
this.state = {
}
}
printValues() {
console.log(document.getElementById('themodule').selectedvalues)
}
render() {
return(
<MyModule id='themodule' />
<button onClick={() => printValues()}>Print values</button>
)
}
}
export default App
Is there a way I can do this?
Thanks!
Edit JS-fiddle here https://jsfiddle.net/xzehg1by/9/
You can create Refs and access state and methods from it. Something like this.
constructor() {
this.myRef = React.createRef();
}
render() { ... <MyModule id='themodule' ref={this.myRef} /> }
printValues() {
console.log(this.myRef)
}
more info here https://reactjs.org/docs/refs-and-the-dom.html
Basically, your state (selectedValues) has to go one level up in the React tree. You have to declare it as App's state, and then pass it down to MyModule via props.
Btw in addValue(), you're not changing any state. And this.selectedValues will be undefined. It's this.state.selectedValues, and this.props.selectedValues once you correct your code.
I think you should first read all react concepts and then start working on it. Anyhow i am modifying your code in one way to get your desired functionality but remember this is not best practice you have to use Redux for this kind of features
import React, { Component } from 'react';
class MyModule extends Component {
constructor() {
super(props);
this.state = {
inputValue : ''
};
this.handleInput = this.handleInput.bind(this);
this.addValue = this.addValue.bind(this)
}
handleInput(e){
this.setState({
inputValue : e.target.value
})
}
addValue() {
this.props.addValue(this.state.inputValue);
}
render() {
return(
<div>
<input type='text' id='textBox1' onChange={handleInput} />
<button onClick={this.addValue}>Add Value</button>
</div>
)
}
}
export default MyModule
and your main component should be
import React, { Component } from 'react';
import MyModule from './myModule.js'
class App extends Component {
constructor() {
super(props);
this.state = {
selectedValues : ''
};
this.printValues = this.printValues.bind(this);
this.addValues = this.addValues.bind(this);
}
printValues() {
console.log(this.state.selectedValues);
}
addValues(val){
this.setState({
selectedValues : this.state.selectedValues + " , "+val
})
}
render() {
return(
<React.Fragment>
<MyModule addValue={this.addValues}/>
<button onClick={this.printValues} >Print values</button>
</React.Fragment>
)
}
}
export default App
This should do your work

this.props.parentFunction is not a function

This is a simple React.js script, but couldn't find the cause. I think this issue is a common doubt for initial React developers. Please help.
The error showing is "this.props.parentClick is not a function".
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
parentClick() {
}
render() {
return (
<div>
<Test childClick={this.parentClick}/>
</div>
);
}
}
class Test extends Component{
constructor(props){
super(props);
this.childClick = this.childClick.bind(this);
}
childClick(){
this.props.parentClick();
}
render() {
return (
<div>
<button onClick={()=>this.childClick()}>click</button>
</div>
);
}
}
render(<App />, document.getElementById('root'));
Here is the code in stackblitz.com.
https://stackblitz.com/edit/react-3zt7qm
Your prop is called childClick not parentClick
Try with:
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
parentClick() {
}
render() {
return (
<div>
<Test parentClick={this.parentClick}/> // Here the name of your prop should be parentClick
</div>
);
}
}
This function inside of your Test component:
childClick(){
this.props.parentClick();
}
should call this.props.childClick(), because thats the prop you passed into the Test component.

React propTypes errors not showing

I'm having problems with React propTyoes. I'v created a component that require 2 props to work as you guys can see in the code below.
When I use the component in the App file, passing just 1 prop, without the "stateSidebarVisible" it doesn't throw me any error/warning from react...
(I read a lot of things about the NODE_ENV production/development, I searched in my node for process.env and didnt found the NODE_ENV variable by the way).
Any clue?
FFMainHeader
export default class FFMainHeader extends React.Component {
render() {...}
}
FFMainHeader.propTypes = {
stateSidebarVisible: React.PropTypes.bool.isRequired,
handleSidebarChange: React.PropTypes.func.isRequired
};
App
This is where i call the FFMainHeader component.
export default class FFMainApp extends React.Component {
.......
render() {
return (
<div id="FFMainApp">
<FFMainHeader
handleSidebarChange={this.onSidebarChange} />
<FFMainSidebar />
</div>
);
}
}
EDIT
export default class FFMainHeader extends React.Component {
constructor(props) {
super(props);
this.clickSidebarChange = this.clickSidebarChange.bind(this);
}
clickSidebarChange(e) {
e.preventDefault();
(this.props.stateSidebarVisible) ?
this.props.stateSidebarVisible = false :
this.props.stateSidebarVisible = true;
this.props.handleSidebarChange(this.props.stateSidebarVisible);
}
render() {
return (
<header id="FFMainHeader">
<a href="#" onClick={this.clickSidebarChange}>
Abre/Fecha
</a>
</header>
);
}
}
FFMainHeader.propTypes = {
stateSidebarVisible: React.PropTypes.bool.isRequired,
handleSidebarChange: React.PropTypes.func.isRequired
};

How to render react component determined by string in TSX

I want to achieve navigation based on hash change in url.
for example for url index.html#HomePage the app will load HomePage component.
import { HomePage } from '../components/homepage'
import { AnotherPage } from '../components/anoterpage'
export class NavigationFrame extends React.Component<any, State> {
constructor(props) {
super(props);
this.state = { pageName: this.pageNameFromUrl() };
}
onHashTagChanged = () => {
this.setState({pageName: this.pageNameFromUrl()});
}
public render() {
var Page = this.state.pageName as any;
return <Page /> //this renders <homepage /> when this.state.pageName = "HomePage";
}
}
is there any way how to dynamically create component based on string?
class CustomComponent extends React.Component{
render(){
return (
var DynamicComponent = this.props.component;
return <DynamicComponent />;
)
}
}
import it into your file and use like below,
return (
<CustomComponent component={this.state.pageName} />
);

Resources