0

I set up an app which has an input box and a title. The title input changes onChange which updates the title shown. The state is an object with an array {title:[{title: 'Welcome', feature: 'test'}] , I successfully setState for title, but feature then becomes unknown. See code:

APP.JS

import React from "react";
import Header from "./Header";

export default class Layout extends React.Component {
  constructor() {
    super();
    this.state = {
      title: [{
        title: 'Welcome',
        feature: 'test'
      }]
    };
  }

  changeTitle(titleChange) {
    this.setState({title: [{title: titleChange }]});
  }

  render() {
    return (
      <div>
        <Header changeTitle={this.changeTitle.bind(this)} title={this.state.title[0].title} feature={this.state.title[0].feature} />
      </div>
    );
  }
}

HEADER.JS

import React from "react";
import Title from "./Header/Title";

export default class Header extends React.Component {
  handleChange(e) {
    const title = e.target.value;
    console.log(e, title);
    this.props.changeTitle(title);
  }

  render() {
    console.log(this.props.title) //This test Works
    console.log(this.props.feature) //This test Works
    return (
      <div>
        <Title title={this.props.title} />
        <h4> Feature Here: {this.props.feature} </h4> //This disappears after I change input
        Title Here: <input value={this.props.title} onChange={this.handleChange.bind(this)} />
      </div>
    );
  }
}

TITLE.JS

import React from "react";

export default class Title extends React.Component {
  render() {
    return (
      <h1>{this.props.title}</h1>
    );
  }}

So app.js is main, header.js is parent, and title.js is child (If I understand correctly).

After I change, title because the new title, but feature becomes undefined. Any idea what's wrong? I might need to use componentWillUpdate but I'm not fully sure how I would.

Kevin Danikowski
  • 4,620
  • 6
  • 41
  • 75
  • 1
    `this.setState({title: [{title: titleChange, feature:this.state.title[0].feature }]});` – Jayce444 Sep 09 '17 at 02:45
  • 2
    Also to reiterate what Andy said, when he says you've made the state 'complicated' he doesn't mean difficult and complex, he means messy and awkward. Based on your question it looks like you don't have much experience with React so making the state as simple as possible will help you at lot. A 'title' property, which is an array with ONE element, that element being an object with 2 properties, one of which is again 'title' is just weird and messy. Would be good to spend a bit of time to think of what exactly you need to store in state and how simplest to store it – Jayce444 Sep 09 '17 at 02:56
  • 1
    Oh Yes I totally agree with you! And I am new at this. This set up made **no** sense, yet it does (EDIT: I think it does) if I were to explain my full design. But thank you so much Jayce your code worked! I really appreciate it! – Kevin Danikowski Sep 09 '17 at 03:41

2 Answers2

3

It's because when you setState you're replacing the title array wholesale with only the inner title property, not feature. Unless you have a specific reason for having such a complicated state I think you should make it less problematic by just using an object:

this.state = { title: 'Welcome', feature: 'test' };

Then set the state:

changeTitle(titleChange) {
  this.setState({ title: titleChange });
}

And build your Header:

<Header
  changeTitle={this.changeTitle.bind(this)}
  title={this.state.title}
  feature={this.state.feature}
/>

If you can't change the structure of your state for whatever reason give the following a go:

  this.setState(Object.assign({}, this.state.title[0], { title: titleChange }));

There's probably a more concise way of writing that without Object.assign, but I can't test it properly. The above code, however, does work.

Edit

This should do the trick:

this.setState({ ...this.state.title[0], title: 'a' });
Andy
  • 61,948
  • 13
  • 68
  • 95
  • Hey Andy, thank you, I do have a reason for making it complicated (this is what I will need for the actual thing I'm developing). I have also used `this.setState({title: [{title: title1 }, {feature: 'test-2'}]});` where you can see feature is specified, but it still comes up undefined :/ – Kevin Danikowski Sep 09 '17 at 02:24
  • @KevinDanikowski, made an amendment to my answer that should set you on the right path. – Andy Sep 09 '17 at 02:47
  • 1
    Thank you so much for the help Andy! So the code which worked was Jayce444's code, for some reason it stated "state is not defined" when I put in yours, however I believe you've led me on the better path, but Jayce's will work for now, thank you so much I really appreciate it! – Kevin Danikowski Sep 09 '17 at 03:43
  • @KevinDanikowsk, I've corrected that in my answer. I wasn't using `this.state` in the jsfiddle and copied it across incorrectly. – Andy Sep 09 '17 at 03:45
  • I did add the `this.` to see if it fixed it, and it hadn't for me for some reason. But either way I believe you've put me on the right path, thank you – Kevin Danikowski Sep 09 '17 at 03:47
  • Could you have a look here? https://stackoverflow.com/questions/67153957/value-becomes-undefined-because-of-setstate/67154970#67154970 –  Apr 20 '21 at 12:29
2

When you are running your set state, you are only specifying your title, not the rest of the properties so they are being set to undefined.

Using the spread operation can help with this (if you have access to it).

this.setState((prevState, props) => {
  return {...prevState, title: [{title: titleChange }]};
});

If not, be sure to include all the other values in the object you set on the state.

k2snowman69
  • 1,849
  • 1
  • 14
  • 19
  • Hey k2Snowman69, I appreciate it, I tried also specifying feature and it didn't work. I just tried your method, no errors, but it didn't fix the problem (feature is still left undefined) :/ any other ideas? thank you – Kevin Danikowski Sep 09 '17 at 02:20
  • 1
    Sorry, stepped away from my computer and went to sleep... Looks like the other answer got you pretty far though! Good luck! – k2snowman69 Sep 09 '17 at 22:05
  • Could you have a loook here? https://stackoverflow.com/questions/67153957/value-becomes-undefined-because-of-setstate/67154970#67154970 –  Apr 20 '21 at 12:30