0

I have been working on this issue for hours but I can't work out what the problem is.

I'm working on a React app which fetches an array of data from an API, but it seems like the array in the component which fetches the data is being affected by a shuffle function in a completely separate component.

It's hard to explain so here's some (simplified, but essentially the same) bits of code:

The fetch bit in Header.js:

fetch("https://example.com")
    .then(result => return result.json())
    .then(data => {
        console.log(data)
        this.props.updateData(data)
    })

Main.js

class Main extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            currentData: []
        }

        this.updateData.bind(this)
    }

    updateData(data) {
        this.setState({currentData: data)}
    }

    render() {
        return(
            <Header updateData={this.updateData} />
            <Body data={data} />
        )
    }
}

The render bit of Body.js

render() {
    return (
        {shuffle(this.props.data).map(item => <p>{item.text}</p>}
    )
}

The shuffle() function

function shuffle(array) {
  var currentIndex = array.length, temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}

The console.log in header.js sends the value of shuffle(data) to the console when that should only be run in body.js after being passed through main.js

Sorry if it makes no sense but I have searched for ages and I need to move on soon

Thanks in advance <3

3
  • if you remove the call to shuffle() in the <Body /> is the console.log() in <Header /> as expected? seems like it might be a reference issue Commented Feb 9, 2018 at 19:32
  • how about shuffle(this.props.data.map(item => <p>{item.text}</p>)) Commented Feb 9, 2018 at 19:35
  • And you have multiple syntax errors in your snippets, like result => return ... or missing )s Commented Feb 9, 2018 at 19:42

1 Answer 1

1

Your shuffle() function is shuffling the array in place, meaning it's updating this.props.data rather than making a separate, shuffled version of it. It's generally a bad idea to update the values of any props or state directly, because it can cause weird issues like this.

If you want to have the shuffle function return a shuffled copy, you can add the line array = array.slice() at the top of that function.

If you'd rather leave shuffle as it is you could alternatively use shuffle(this.props.data.slice()).map(...) or shuffle(this.props.data.map(...)) since both of these create new arrays before shuffling them.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer, it fixed the problem. I was just wondering, why does React do this? It would (sort of) make sense at one level, updating the props of the body object, but I find it extremely strange that it updates the state of the main object, which updates the data object received by the fetch function in header. Do you know why this is?
Yeah, it can be a bit confusing to keep track of this kind of thing. This is more of a Javascript issue than a React one, honestly. When you pass down the Array this.data as a prop to Body, you're passing down a reference to the array rather than a copy of the array, so anything you do directly to this.props.data in Body affects the referenced array rather than a new one. This is the same as if you were to run something like: let arr1 = [1,2,3]; let arr2 = arr1; arr2[0] = 'abc'; console.log(arr1[0]); // 'abc' since both arr1 and arr2 are referring to the literal same array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.