2

As the title suggests, I'm attempting to target an array inside of my state object but as you would guess if you ever tried. This isn't as straightforward as it sounds. I've looked through a couple of questions here (React: How do I update state.item[1] on setState? (with JSFiddle) and ReactJS - setState of Object key in Array) but neither are solving my problem.

What I need is to target a specific index inside of the noteData array, and update it according to whatever a user types into the <TextArea /> component. Not exactly sure why but my noteData array just read as an array with an empty string noteData = [''].

If you need a more in-depth look, you can go to https://stackblitz.com/edit/note-taking and fork the page and edit it yourself. The file structure is goofy to the say the least. I started using redux and decided against it halfway through.

state and functions TextArea

class NoteList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: '',
      noteName: [],
      noteData: [],
      selectedNote: []
    }
}

  handleInputValue(e) {
    this.setState({
      inputValue: e.target.value
    });
  }

  addNoteFunc(e) {
    this.setState({
      noteName: [ ...this.state.noteName, e.target.value ],
      noteData: [ ...this.state.noteData, '' ]
    });
  }

 // everytime the user types, change the value of noteData
  handleNoteData(e, index = this.state.selectedNote[0]) {
    const copyNoteData = Object.assign({}, this.state);
    copyNoteData.noteData[index] = e.target.value;

    this.setState(copyNoteData);
  }

  handleSelectedNote(index) {
    this.setState({
      selectedNote: [ index ]
    });
  }

<textarea 
  value={this.state.noteData[this.state.selectedNote[0]]}
  handleNoteData={(e, index) => this.handleNoteData(e, index)}
/>

The actual TextArea component

import React from 'react';

const TextArea = props => {
  return (
    <div className='textarea'>
      <textarea 
        value={props.value}
        onKeyDown={props.handleNoteData}
      />
    </div>
  );
}

export default TextArea;
Brandon Benefield
  • 1,504
  • 1
  • 21
  • 36
  • `index` will always be undefined in this setup. Here you are expecting index: `handleNoteData={(e, index) => this.handleNoteData(e, index)}`, but in you're not passing that in here `onKeyDown={props.handleNoteData}`. So `index` will always end up being the same thing. That may be the reason. – Chase DeAnda Oct 09 '17 at 18:13
  • And your `handleSelectedNote` function is overwriting the state each time with a new array. So `this.state.selectedNote` will never have a length more than 1. – Chase DeAnda Oct 09 '17 at 18:15
  • So `state.selectedNote` is supposed to be a length of 1, always. It is as the name suggests, the currently selected note which can only be one. In my `handleNoteData` func, im not sure if I'm doing it right but the `index` argument is defined as `this.state.selectedNote[0]`... `handleNoteData(e, index = this.state.selectedNote[0])` so I should not need to pass a value later on, as it has already been defined, or am I using this incorrectly? – Brandon Benefield Oct 09 '17 at 18:19
  • Why is it in an array then? Couldn't you just save the `index` as a number? – Chase DeAnda Oct 09 '17 at 18:20
  • I guess it could, but I was not sure if reading a string that is a number could be referenced later as an index. – Brandon Benefield Oct 09 '17 at 18:22

1 Answers1

2

you have error in your code, as textarea is not the correct component it should be TextArea and not textarea which is a html element, and you will first have to first import it in notelist.js, That is why onKeyDown props is not being set.

<TextArea 
   value={this.state.noteData[this.state.selectedNote[0]]}
   handleNoteData={(e, index) => this.handleNoteData(e, index = this.state.selectedNote[0])}
/>

Also you must add handleNoteData to onChange event otherwise in onKeyDown event texarea value wil never change since you are resetting it to e.target.value each time.

try this: https://stackblitz.com/edit/note-taking-y5hwsb?file=containers/notelist.js

Dij
  • 9,761
  • 4
  • 18
  • 35
  • Wow, that is a pretty bad typo on my part, thanks for catching that. So how would you suggest instead of it statically rendering 'Hello', I am able to reference an index of `noteData` and use the value of that instead? – Brandon Benefield Oct 09 '17 at 18:26
  • `copyNoteData.noteData[index] = 'Hello'` you are setting it to Hello, what do you want it to be? – Dij Oct 09 '17 at 18:31