Append items from one array to another, then if button is clicked on, move the last item back

Viewed 44

I'm building a function to help me with moving items from the arrays. Component renders various sections:

  1. filledArray - an array of null's, that produces a dynamic amount of buttons depending on the length of the word.
  2. bottomLetters - an array of letters, where the word has been split onto each individual letter. Once the letter is clicked on it will append a new item in filledArray.
  3. delete button - once clicked on, deletes the last item within the topLetter array and adds the back to the bottomLetters array..

Now I have two issues with the code:

  1. It does not update the render automatically. I'd have to save the code sandbox to generate the result.
  2. When clicking on delete button it breaks the value of the items in the bottomLetters array. (For example try clicking on three items from bottomLetters array, hit save and then hit delete button, it won't move the items back to the array).

This is the code example that I have: https://codesandbox.io/s/show-and-hide-in-react-forked-nh9l2?file=/src/MyApp.js

1 Answers

You need the state object for storing the local variable that needs to be automatically updated by React. To be able to use state object, you must convert your functional component code to class component.

Here are some changes I made to fix the problems.

import React, { Component } from 'react';

export class myApp extends Component {
  state = {
    word: ['1234'],
    topLetters: [],
    bottomLetters: [],
    filledArray: [],
  };

  componentDidMount() {
    this.setState({
      bottomLetters: [...this.state.word[0]],
      filledArray: new Array(this.state.word[0].length).fill(null),
    });
  }

  handleLetters2Click = (letter, id) => {
    this.setState({ topLetters: [...this.state.topLetters, { letter }] });

    let bottomLetters = [...this.state.bottomLetters];
    bottomLetters.splice(id, 1);
    this.setState({ bottomLetters });
  };

  deleteLast = () => {
    if (!this.state.topLetters.length) return;

    const lastTopLetter = this.state.topLetters.length - 1;
    const lastLetter = this.state.topLetters[lastTopLetter].letter;

    let topLetters = [...this.state.topLetters];
    topLetters.pop();
    this.setState({ topLetters });

    let bottomLetters = [...this.state.bottomLetters];
    bottomLetters.push(lastLetter);
    this.setState({ bottomLetters });
  };

  render() {
    const { filledArray, topLetters, bottomLetters } = this.state;

    return (
      <div style={{ display: 'flex', flexDirection: 'column' }}>
        <div style={{ marginBottom: '40px' }}>
          {filledArray.map((index, id, item) => (
            <button key={id} className='item'>
              {topLetters[id] && topLetters[id].letter}
            </button>
          ))}
        </div>
        <div>
          {bottomLetters.map((index, id, item) => (
            <button
              key={id}
              className='item'
              onClick={() => this.handleLetters2Click(item[id])}
            >
              {item[id]}
            </button>
          ))}
        </div>
        <button onClick={this.deleteLast} style={{ marginTop: '40px' }}>
          DELETE
        </button>
      </div>
    );
  }
}

export default myApp;
Related