0

I am working on a component that includes multiple sub components that can be selected (or 'activated', as the naming here says.). I have an array of IDs which should be initialised with all IDs being selected, so this.state.activeSensors refers to the total list of sensors: this.props.mainViewSensors. The functions sensorSelect gets the ID, and should by this be able to determine if it is selected or not. My approach has been to check if it is in the activeSensors list- Remove it if it's there, add it if it's not. Set the new state.

When I remove an item from the new list newActiveSensors and call the setState, the clicked item somehow disappears from the props as well. I did not know that this was possible. Is it something I have done wrong?

Here is what I did:

const propTypes = {
  mainViewSensors: PropTypes.arrayOf(PropTypes.string),
};

const defaultProps = {
    mainViewSensors: [
        '21EL',
        '05LO',
        '08HT',
        '81EL',
        '05TF',
    ],
}

class Multiselect extends React.Component {
    constructor(props) {
        super(props);
        this.sensorSelect = this.sensorSelect.bind(this);
        this.state = {
            activeSensors: this.props.mainViewSensors,
            selectedSensors: this.props.mainViewSensors,
        };
    }

  sensorSelect(sensor) {
    const newActiveSensors = this.state.activeSensors;
    if (newActiveSensors.includes(sensor)) {
        const index = newActiveSensors.indexOf(sensor);
        newActiveSensors.splice(index, 1);
    } else {
        newActiveSensors.push(sensor);
    }
    this.setState({
        activeSensors: newActiveSensors,
    });
  }

    render() {
    const { selectedSensors, activeSensors } = this.state;

    return (
    <div className="wrapper">
        {this.state.selectedSensors.map((tag) => (
            <div key={tag} role="button" className="main-gauge-holder" onClick={this.sensorSelect(tag)}>
                <MainGauge tag={tag} />
            </div>
        ))}
    </div>
    );
  }
}

Multiselect.propTypes = propTypes;
Multiselect.defaultProps = defaultProps;

React.render(<Multiselect />, document.getElementById('container'));

Just to make it clear, I'm making something like this, where the green arrow show which one is selected (here I have manually changed the active state in child component):

Kristoffer Lund
  • 209
  • 3
  • 14

1 Answers1

2

This is actually not a React problem, your just using the same instance of the array over you class. You have to make a new array in order to use a copy of it.

See my example for clarification :

var primaryArray = [1, 2, 3];

console.log('Init :');
console.log(primaryArray);

var obj = {
  array: primaryArray, // Same instance
  clonedArray: primaryArray.slice() // Clone
};

console.log(obj);

console.log('Poping from the same instance :');
obj.array.pop();

console.log(obj);
console.log(primaryArray);

console.log('Poping from the cloned array doesn\'t affect primary one :');
obj.clonedArray.pop();

console.log(obj);
console.log(primaryArray);
Serge K.
  • 5,303
  • 1
  • 20
  • 27
  • Oh my, this worked like a charm! I thought that the const in the beginning of the function did make a copy, and I didn't think more of it as all my attention went to the props change.. Thank you so much! – Kristoffer Lund Jul 20 '17 at 12:00