Can't access properties of an object - reactjs

I can't access the keys of the object that I pass through props to my EditField component. When I log the prop I passed into the console it outputs the object correctly, but when I try to get any key of that object I get an "undefined error". What's up with that object? On the picture is the object I get when doing console.log(department) Look at my code:
class EditForm extends React.Component {
render() {
const departments = this.props.departments
const showcasedDepName = this.props.showcasedDepName
const dep = departments.filter(dep => dep.depName ===
showcasedDepName)[0]
return(
...irrelevant stuff
<EditField department={dep}/>
</form>
</div>
)
}
}
EditField component:
class EditField extends React.Component {
render() {
const department = this.props.department
console.log(department.depName) //"undefined", whereas it shows me the correct object when I do console.log(department)
return(
<div className="edit-dep">
<div>Department name: <input type="text" value=
{department.depName}/></div>
</div>
)
}
}

I fixed it! The problem came from where I didn't expect it to come. I counted the amount of workers in componentDidMount function where I changed the state of 'depAmount' key from null to the length of the array of workers. When I replaced componentDidMount with componentWillMount the problem dissappeared. I guess the reason why I had this error is that the state initially rendered with null value.

Related

Pass properties in a component React by a Razor page, value are not showen

i have a project ASP.NET CORE MVC and i want to pass an object of the Model in a component react. My purpose is to pass a list of object but doesn't find simple properties of the object passed for test. The properties seems to be undefined, how con i pass it correctly??
[EDIT] Now is not undefined anymore but nothing is showen. And i can't use console.log to check the value of props cause seems to not show simple message too.
class App extends React.Component{
componentDidMount() {
console.log('hi')
}
render() {
const { Property1, Property2 } = this.props;
return (
<div>
<p>Property1: {Property1}</p>
<p>Property2: {Property2}</p>
<div className="box">Sono un box</div>
</div>
);
}
}
Index.cshtml:
#Html.React("App",new { Property1 = "value1", Property2 = "value2" })
The file has only this string of code cause i want only a component to be insert, but as you can see in the inspector it's not a component called App but a div with an id, is it correct?
[EDIT]
this is how the page looks in the inspector:
The props are passed to the component constructor and are available as this.props inside render():
class App extends React.Component {
render() {
const { Property1, Property2 } = this.props;
return (
<div>
<p>Property1: {Property1}</p>
<p>Property2: {Property2}</p>
<div className="box">Sono un box</div>
</div>
);
}
}

How to Pass Object Values to Children in ReactJS

I am trying to pass an object from Parent to Child as described in this article.
I am new to React JS and am probably missing something simple here.
The goal of this is to have a select list of "Industries" that passes the selected industry to a select list of "Categories". The selected Category would then populate a table.
I am getting the error that this.props.selectedIndustry doesn't exist on compile.
Here is my code:
class CategoryFilter extends React.Component {
constructor(props) {
super(props);
this.state = {
industrySelect: this.props.selectedIndustry
}
console.log(this.props.selectedIndustry)
}
render() {
const { selectedCategory } = this.state;
const categories = utmcategories.filter(function(i) {return i.industry==this.props.selectedIndustry})
return (
<Select options={categories} onChange={this.handleCategoryChange}
/>
);
}
class IndustryFilter extends React.Component {
state = {
selectedIndustry: null,
};
handleIndustryChange = (selectedIndustry) => {
this.setState({ selectedIndustry });
console.log(`Option selected:`, selectedIndustry);
}
render() {
const { selectedIndustry } = this.state;
const industries = utmindustries;
return (
<div>
<Select options={industries}
onChange={this.handleIndustryChange}
autoFocus={true}
/>
<CategoryFilter selectedIndustry={selectedIndustry}/>
</div>
);
}
}
I modified the code to narrow down the issue and made my CategoryFilter this:
function CategoryFilter(props) {
return (
<div>
{props.filteredIndustry}
</div>
)
}
But still got the error:
"Objects are not valid as a React Child."
You are initialising selectedIndustry to null here:
state = {
selectedIndustry: null,
};
and then passing it in as a prop to <CategoryFilter>
I am getting the error that this.props.selectedIndustry doesn't exist
on compile. Here is my code
Not quite sure that the 'error' you are getting is actually an error. Seems like it may be the expected behaviour. Could you please show us the error message exactly?
I would expect this.props.selectedIndustry to be defined as null after <CatergoryFilter> has mounted. You should try initialising it to a value e.g. "Default Industry" and see if that console.log(this.props.selectedIndustry) in the constructor is printing "Default Industry". If not, I would suspect that the this context has not been initialised until after the constructor has returned. Try logging this value in the render() method instead.

this.setState is not updating the state property

I am setting the state in a method call from a constructor but the state property is still null. Some modification on the code gives be this error in the console,
index.js:1375 Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to this.state directly or define a state = {}; class property with the desired state in the ResultContainer component.
In my component constructor i am calling a method. That method in turn calls another method and is trying populate an state property with an array. I get two different variants of error/warning. In my code if uncomment the lines inside render method i get searchedAddress is null error. if i leave the lines as commented then in the console i get the above error.
On my render() method i can check for null and that certainly does not throw and error but the the result items are not getting loaded no matter what i do. this question, State not changing after calling this.setState seems somewhat relevant but i am not sure i could i re-render the item asynchronously.
import React from 'react';
import ResultItem from './ResultItem'
import AddressService from '../Api/AddressService'
class ResultContainer extends React.Component{
constructor(props){
super(props);
this.state = {
searchedAddresses : null
}
this.intiateSearch();
}
intiateSearch =() => {
if(this.props.searchedTerm != null){
var addressService = new AddressService();
//this is just getting an items from json for now. i checked and result does contain items
var result = addressService.searchAddress(this.props.searchedAddresses);
//the below line does not seem to work
this.setState({
searchedAddresses : result
});
}
}
render(){
return(
<div className="mt-3">
<h4>Seaching for postcode - <em className="text-primary">{this.props.searchedTerm}</em></h4>
<div className="container mt-1">
{
//below gives an error stating searchedAddresses is null
// this.state.searchedAddresses.map((address, index)=>{
// return(<ResultItem address={address}/>);
// })
}
</div>
</div>
);
}
}
export default ResultContainer;
You shouldn't call component functions inside of the constructor method, the component is not yet mounted at this point and therefore your component functions aren't available to be used here yet. In order to update your state. You used to be able to use the componentWillMount lifecycle method but that is now considered legacy. You should be calling any component initializing functions inside of the componentDidMount lifecycle method.
Change your code like so :
(Notice the check for state initially being null in the render function)
import React from 'react';
import ResultItem from './ResultItem'
import AddressService from '../Api/AddressService'
class ResultContainer extends React.Component{
constructor(props){
super(props);
this.state = {
searchedAddresses : null
}
}
componentDidMount() {
this.intiateSearch();
}
intiateSearch =() => {
if(this.props.searchedTerm != null){
var addressService = new AddressService();
//this is just getting an items from json for now. i checked and result does contain items
var result = addressService.searchAddress(this.props.searchedAddresses);
this.setState({
searchedAddresses : result
});
}
}
render(){
return(
<div className="mt-3">
<h4>Seaching for postcode - <em className="text-primary">{this.props.searchedTerm}</em></h4>
<div className="container mt-1">
{
this.state.searchedAddresses !== null &&
this.state.searchedAddresses.map((address, index)=>{
return(<ResultItem address={address}/>);
})
}
</div>
</div>
);
}
}
export default ResultContainer;
I see you're calling this.intiateSearch(); in constructor which will call setState on a not yet mounted component.
So why don't you call this.intiateSearch(); inside componentDidMount() lifecyle after the component is mounted?
componentDidMount() {
this.intiateSearch();
}

Typescript React Component get return value

How can I get result from component class with this way?
this my how I called ExampleSelectionComponent, it shows me what I want to see but need to get exampleSelectionId value on this class.
public render() {
const { exampleId } = this.state;
return(
<div>
<tr>
<ExampleSelectionComponent id="ExampleSelection"
exampleSelectionId={exampleId}
tabId={this.props.tabId}/>
</tr>
</div>
)
}
You'll likely have to pass down a method that updates the state of this parent component.
class ParentComponent extends Component<any, any> {
constructor(props:any){
super(props);
this.state = {
exampleId: 123,
}
}
private setSelectionId(newId: number) {
this.setState({exampleId: newId});
}
public render() {
const {exampleId} = this.state.exampleId;
return (
<div>
<tr>
<ExampleSelectionComponent id="ExampleSelection"
updateSelectionId={this.setSelectionId}
tabId={this.props.tabId} />
</tr>
</div>
)
}
}
Then from within your ExampleSelectionComponent call updateSelectionId when you want to change it in the parent.
Yes! you are right, I need to explain a bit more,
I have two .tsx (Example and ExampleSelectionComponent). I'm calling my ExampleSelectionComponent.tsx from Example.tsx.
ExampleSelectionComponent.tsx has a TextField and I can change it. when I change it, I'm updating state value in it (value).
That's what I want: If I changed textfield value in ExampleSelectionComponent.tsx on browser and then I clicked DefaultButton in Example.tsx. its gonna make work getExampleSelectionComponentTextFieldValue() and I wanna put ExampleSelectionComponent TextField value there.
Im adding two pictures from classes at down;
Example.tsx
ExampleSelectionComponent.tsx

React pass data to parent error this.props. is not a function

I am trying to pass data from child to parent. Im not sure why I am getting this console error
TypeError: this.props.aaaaaaaaaa is not a function
Code:
class GenericInputWithLabel extends React.Component {
constructor(props) {
super(props);
this.handleInputChange = this.handleInputChange.bind(this);
}
renderLabel() {
return (
<div style={labelDiv}>
{this.props.label}
</div>
)
}
handleInputChange(inputStr) {
initialValue={this.props.initialValue}
this.props.aaaaaaaaaa(inputStr);
}
render() {
return (
<div style={parentDiv}>
<div style={inputDiv}>
<CustomNumberInput
initialValue={this.props.initialValue}
onInputChange={this.handleInputChange}/>
</div>
{this.props.label && this.renderLabel()}
</div>
);
}
}
export default GenericInputWithLabel;
Also, the console log I put in inside the handleInputChange does log out the initial value I pass in. This means that the function does have the right context of this. Why would it complain when I want to pass data with
this.props.aaaaaaaaaa(inputStr)
---Update----
<GenericInputWithLabel
label="test"
initialValue={123}
aaaaaaaaaa={this.handleChange}/>
Iv found the problem. It is actually the parent container.
I didn't realise parent container would be the cause.
My constructor this.bind had a typo so everything was not working as expected
You should defined aaaaaaaaaa as a function
<GenericInputWithLabel aaaaaaaaaa={(str) => console.log(str)}/>

Resources